Arquitectura de Aplicaciones

1

¡Renovaremos este curso! Te quedan unos días para concluirlo.

2

Pasos para aprender Flutter Avanzado

3

¿Qué es una Arquitectura de software?

4

Tipos de Arquitecturas para Flutter

5

Arquitectura BLoC en Flutter

6

¡Renovaremos este curso! Te quedan unos días para concluirlo.

7

BLoC + Clean Architecture en Flutter

8

Estructurando nuestro proyecto utilizando la Arquitectura BLoC

9

Haciendo BLoC Singleton en Flutter

10

Aplicando Providers al Proyecto

Firebase y Flutter

11

¡Renovaremos este curso! Te quedan unos días para concluirlo.

12

Integrando Firebase Authentication, Cloud Firestore y Firebase Storage al proyecto

13

Integrando Firebase a Flutter para iOS

14

Integrando Firebase a Flutter para Android

15

Creación de Pantalla de Login con Flutter

16

Creando botones reutilizables en Flutter

17

Autenticación de Firebase con Google

18

¡Renovaremos este curso! Te quedan unos días para concluirlo.

19

Implementando Firebase Authentication en BLoC Pattern

20

Streams en Flutter

21

Manejando una sesión con Firebase Authentication y Flutter

22

Implementando Google SignOut en BLoC

23

Implementando Google SignOut en View

24

Monitoreando y validando la conexión al Sign con Google

25

Mostrando los datos de usuario de Google en la interfaz en Flutter

Cloud Firestore de Firebase en Flutter

26

¡Renovaremos este curso! Te quedan unos días para concluirlo.

27

¿Qué es Cloud Firestore de Firebase?

28

Analizando un modelo de datos no relacional

29

Creando un Modelo de datos en Cloud Firestore

30

Enviando datos a Cloud Firestore

31

Creando un Widget gradiente personalizado

32

Manejo de Desbordamiendo de Texto de Widget Text

33

Botón de Back en un Appbar en Flutter

34

Navegación entre pantallas en Flutter

35

Widget Text Appbar personalizado en Flutter

36

¡Renovaremos este curso! Te quedan unos días para concluirlo.

37

Widget TextField personalizado en Flutter

38

Creando una Safe Area para una interfaz que tiene un AppBar

39

Widget TextField con iconos en Flutter

40

Retocando el CardView

41

Mostrando imágenes en un CardView

42

Creando un botón de Submit en Flutter

43

Envío de datos de un fórmulario en Flutter

44

Subiendo datos a Firestore de Firebase

45

Formularios en Flutter

Acceso al Hardware con Flutter

46

¡Renovaremos este curso! Te quedan unos días para concluirlo.

47

Acceso a la cámara en Flutter

48

Librerías de acceso a Hardware en Flutter

Firebase Storage en Flutter

49

¡Renovaremos este curso! Te quedan unos días para concluirlo.

50

Qué es y cómo funciona Firebase Storage en Flutter

51

Subiendo una imagen a Firebase Storage desde Flutter

Querys avanzados en Cloud Firestore de Firebase en Flutter

52

¡Renovaremos este curso! Te quedan unos días para concluirlo.

53

Manejo de imágenes en Cloud Firestore

54

Cloud Firestore insertando referencias y arrays en la base de datos

55

Descargar imágenes de Firebase Storage y mostrarlas en Flutter

56

Procesando datos con BLoC Pattern

57

Trayendo datos de Cloud Firestore

58

Persistiendo datos de un usuario logueado

59

Aplicando Filtros en Cloud Firestore

60

¡Renovaremos este curso! Te quedan unos días para concluirlo.

61

Construyendo los Places en la pantalla de Home

62

Mostrando los Places en la pantalla de Home

63

Actualizando datos en tiempo real

64

Manejando la lógica de likes, como botón toggle.

65

Insertando y obteniendo referencias en datos de Firestore.

66

Usando el caché para cargar imágenes más rápido

67

StreamController, sink, add y StreamBuilder

Conclusiones

68

¡Renovaremos este curso! Te quedan unos días para concluirlo.

69

Conclusiones

No tienes acceso a esta clase

¡Continúa aprendiendo! Únete y comienza a potenciar tu carrera

Aprende todo un fin de semana sin pagar una suscripción 🔥

Aprende todo un fin de semana sin pagar una suscripción 🔥

Regístrate

Comienza en:

0D
23H
57M
51S
Curso Avanzado de Flutter

Curso Avanzado de Flutter

Anahí Salgado Díaz de la Vega

Anahí Salgado Díaz de la Vega

Manejo de imágenes en Cloud Firestore

53/69
Recursos

Aquí está el repositorio de esta clase.

Aportes 19

Preguntas 1

Ordenar por:

¿Quieres ver más aportes, preguntas y respuestas de la comunidad?

o inicia sesión.

No se está guardando la url de la imagen de ese Place, para ello hay que modificar el archivo User/repository/cloud_firestore_api.dart, y agregar el key ‘urlImage’

Future<void> updatePlaceData(Place place)async{
    CollectionReference refPlaces = _db.collection(PLACES);
    String uid = (await _auth.currentUser()).uid;
    await refPlaces.add({
      'name': place.name,
      'description': place.description,
      'likes': place.likes,
      'userOwner': "$USERS/$uid",
      'urlImage': place.urlImage,
    });
  }```

Si les molesta la cadena de callbacks o ‘callback hell’, pueden hacer una función asíncrona y esperar por los resultados. En caso de ser nulos, terminar la función.

  void handleUpload(BuildContext context) async{
    //Subir img a firebase storage
    final String uid = (await userBloc.currentUser).uid;
    if(uid == null) {
      print('Null uid');
      return;
    }
    final uploadTask = await userBloc.uploadFile('$uid/${DateTime.now().toString()}.jpg', widget.image);
    if(uploadTask == null){
      print('Null upload task');
      return;
    }

    //Firebase store devuelve la url de la img
    final taskSnapshot = await uploadTask.onComplete;
    if(taskSnapshot == null){
      print('Null task snapshot');
      return;
    }

    final imageUrl = await taskSnapshot.ref.getDownloadURL();
    if(imageUrl == null){
      print('Null image URL');
      return;
    }

    print('Image url: $imageUrl');

    //Subimos a Firestore el Place (title, description, urlImg, userOwner, likes...)
    userBloc.updateUserPlace(
        Place(
          name: _controllerTitlePlace.text,
          description: _controllerDescriptionPlace.text,
          where: _controllerInputLocation.text,
          imagePath: imageUrl,//firebase storage url
          likes: 0,
        )
    ).whenComplete( () {
      print('Termino la subida de la imagen');
      Navigator.pop(context);
    });
  }

Nuevamente el curso esta bastante desactualizado respecto a los cambios que ha sufrido Fluuter, para que funcione el onPressed de agregar un place, se debe ajustar ahora de la siguiente manera:

onPressed: () {
       userBloc.currentUser().then((User user) {
         if (user != null) {
              String uid = user.uid;
              String path = "$uid/${DateTime.now().toString()}.jpg";
              
	      // Firebase storage
	      userBloc.uploadFile(path, widget.imagen).then((storageTask) {
                storageTask.then((TaskSnapshot snapshot) {
                snapshot.ref.getDownloadURL().then((urlImage) {
                     print("URL: " + urlImage);
                     userBloc.updatePlaceData(Place(
                        name: _controllerTitlePlace.text,
                        descripcion: _controllerDescription.text,
                        urlImagen: urlImage,
                        likes: 0)).whenComplete(() {
                                print("Termino updatePlace");
                                Navigator.pop(context);
                         });
                     });
                  });
               });
             }
         });
      }), 

A tener encuenta, actualmente para subir la imagen hay que modificar la “Rule” en la consola de Firebase Storage y colocarla asi:

rules_version = '2';
service firebase.storage {
  match /b/{bucket}/o {
    match /{allPaths=**} {
      allow read, write: if request.auth != null;
    }
  }
}

Aca dejo mi repositorio que ya funciona al subir la imagen

Hay que informarle al usuario mientras se carga la imagen 😃

Por si alguien tenia problemas con UploadFile 😃

En el archivo '‘add_place_screen’

userBloc.uploadFile(path, widget.image).then((takeSnashot) => {
  takeSnashot.ref.getDownloadURL().then((urlPlace) {

    userBloc.updatePlaceData(Place(
      name: _controllerTitlePlace.text,
      description: _controllerDescripcionPlace.text,
      urlImage: urlPlace,
      likes: 0,

    )).whenComplete(() {
      print("Termino la subida de data");
      Navigator.pop(context);
    });
  })
});
	                 	

En el archivo ‘firebase_storage_api’

class FirebaseStorageAPI {

  final Reference _storageReference = FirebaseStorage.instance.ref();

  Future<TaskSnapshot> uploadFile(String path, File image) async {

    UploadTask uploadTask = _storageReference.child(path).putFile(image);
    TaskSnapshot taskSnapshot = await uploadTask.whenComplete(() => null);

    return taskSnapshot;
    
  }
}

Para el emulador de IOS uno puede cambiar, en ves de tomar una foto con la camara, cambiar el source y abrir la galeria

Excelente de momento no e tenido problemas con el desarrollo de la aplicación solo presten mucha atención a lo que se esta haciendo donde se esta pasando cada función o variable. Excelente curso complementando con los demás de Android.

La forma en la que estan estructurando el código en el curso sigue sin ser la mas limpia y estructurada, pero a día de hoy (2022), esta fue la implementación para el uso de Storage

Container(
  width: 70.0,
  child: Button(
    buttonText: "Add Place",
    onPressed: () {
      // firestorage
      // obtenemos la url de la imagen
      userBloc.currentUser.then((user) {
        if (user != null) {
          String uid = user.uid;
	 			  // Se debería obtener el mimeType del file
          String path = "$uid/${DateTime.now().toString()}.jpg";
          userBloc.uploadFile(path, widget.image).then((UploadTask storageTask) {
            storageTask.then((TaskSnapshot snapshot) {
              snapshot.ref.getDownloadURL().then((imageUrl) {
                // guardamos la info en cloud firestore
                // Place object - title, description, url, userOwner, likes
                userBloc.updatePlaceData(Place(
                    name: _controllerTitlePLace.value.text,
                    description: _controllerDescriptionPlace.value.text,
                    likes: 0,
                    urlImage: imageUrl
                )).whenComplete(() {
                  print("Termino");
                  Navigator.pop(context);
                });
              });
            });
          });
        }
      });
    },
  )
),

Así me funcionó, obteniendo el TaskSnapshot a través del onCompleted que tiene el UploadTask

Future<void> createPlace(Place place, XFile file) async {
    String mimeType = file.mimeType ?? "jpg";
    File image = File(file.path);
    UploadTask task = await repository.updaloadFile(image, mimeType);
    TaskSnapshot snapshot = await task.whenComplete(() => null);
    String imageURL = await snapshot.ref.getDownloadURL();
    place.photos.add(imageURL);
    await repository.createPlace(place);
  }

Bueno desde ya hace un rato me sale el error de que no muestra la imagen que tomo con la camara me aparece asi:
luego para verificar que pasaba le puse en vez camara con gallery y me funciono perfecto pero aun asi no me muestra o lo visualiza la imagen despues de seleccionar la foto:
pero al guardarlo si me aparece eso demuestra que realmente si esta guardando pero si lo coloco con camara no me muestra nada solo la pantalla de Profile

en userBloc.uploadFile(path, wigets.image) .then ((StorageUploadTask storageUploadTask){ me esta devolviendo un null })

alguien sabe por que me devuelve un null ? y eso que me sube la imagen a storage de firebase.

faltaría agregar un progress bar mientras se está enviando la imagen, y bloquear en boton… de lo contrario si se pulsa 3 veces el boton, guarda 3 veces la misma imagen

Excelent! me funciono a la primera yupiiiiiii

Hola compañero si no te salio, te recomiendo que vayas a la clase donde se implementa el uso de la cámara con image_picker ahí te deje la solución. Saludos!

Funcionando bien hasta ahora! 😉

Todo perfecto!

A mi no me sirvio completamente lo de la clase pero finalmente me quedo asi:

`onPressed: () {
String uid = userBloc.currentUser.uid;
String path = “${uid}/${DateTime.now().toString()}.jpg”;
final uploading = userBloc.uploadFile(path, widget.image);

//SUBIR FOTO DE LA CAMARA
uploading.then((storageTask) {
//GUARDAR DATOS EN BD
userBloc.updatePlaceDataMongo(Place(
name: _controllerTitlePlace.text,
description: _controllerDescriptionPlace.text,
likes: 0, uriImage: storageTask.ref.fullPath
)).
then((value) {
print(“Termino de guardar el nuevo lugar”);
Navigator.pop(context);
});
}).catchError((onError){
print(“Error al guardar el nuevo lugar ${onError}”);
});
}
`

Para aquellos que estan usando la clase PickedFile y la necesitan convertir a File, el metodo quedaria asi:

//1. Firebase Storage
                      userBloc.currentUser
                      .then((FirebaseUser user) {
                        if(user != null) {
                          String userId = user.uid;
                          String path = '${userId}/${DateTime.now().toString()}.jpg';
                          userBloc.uploadFile(path, File(widget.image.path))
                          .then((StorageUploadTask storageUploadTask) {
                            storageUploadTask.onComplete
                                .then((StorageTaskSnapshot snapshot) {
                                  snapshot.ref.getDownloadURL()
                                      .then((urlImage) {
                                        print('URLImage: ${urlImage}');
                                        //2. Cloud function
                                        userBloc.updatePlaceDate(Place(
                                          name: _controllerTitlePlace.value.text,
                                          description: _controllerDescriptionPlace.value.text,
                                          likes: 0,
                                          urlImage: urlImage

                                        )).whenComplete(() {
                                          print('Added place');
                                          Navigator.pop(context);
                                        });
                                  });
                            });
                          });

                        }

Solo instancien un File con el path de la imagen

File(widget.image.path)