I am having trouble defining path for Firebase cloud storage. I would like it to be -

user id -> firestore doc id -> folder's name.

currently, I successfully save the images in this way.

class FirebaseStorageService {
final String imageName;
FirebaseStorageService({required this.imageName});

  get imageFileName =>
      imageName + DateTime.now().millisecondsSinceEpoch.toString();

//get firestore doc id  
final postid = FirebaseFirestore.instance.collection('properties').doc().id;

//get user id
final String? userid = FirebaseAuth.instance.currentUser!.uid;

  //! Upload gallery
  Future<String> saveGalleryInCloudStorage({
    required File file,
  }) async =>
      await upload(
          file: file,
          path: '$userid/$postid/Property Gallery/$imageFileName',
          contentType: 'image/png');

  /// Generic file upload for any [path] and [contentType]
  Future<String> upload({
    required File file,
    required String path,
    required String contentType,
  }) async {
    final storageReference = FirebaseStorage.instance.ref().child(path);
    final uploadTask = storageReference.putFile(
        file, SettableMetadata(contentType: contentType));
    final snapshot = await uploadTask;
    final downloadUrl = await snapshot.ref.getDownloadURL();
    return downloadUrl;
  }
}

However, the problem I am having is the postid (that is used in firebase cloud storage path) is not same with firestore doc id.

see my database screenshot

How do I make them to be the same? Thanks in advance!!


Solution 1: griffins

.collection('properties').doc() the doc is empty hence firebase generates an auto id.

What you can do is Create an empty doc get a doc id, use the id to save the file, and when saving your firestore doc just update the empty doc

  1. create empty doc

final documentReference = await FirebaseFirestore.instance.collection('mycoll').add({'id':''});

  1. use doc id to save file obtained from documentReference.id

makes this redudant

//get firestore doc id  
final postid = FirebaseFirestore.instance.collection('properties').doc().id;
  1. on done saving file , save your doc with the id above
FirebaseFirestore.instance.collection('properties').doc(documentReference.id)
        .set(servicemodel.toJson());```


Solution 2: Zekai Demir

You can upload Image and update fields related withthis function. Its work for me.

static String staticImagePath= "";
 final FirebaseAuth _auth = FirebaseAuth.instance;
  File? file;

  Future uploadImageToFirebaseStorage() async {
        var _user = _auth.currentUser!.uid;

        var _propertiesCollection= FirebaseFirestore.instance
            .collection('Properties')
            .where('postId', isEqualTo: _user);
        var querySnapshots = await _propertiesCollection.get();

        try {
          var _image = await ImagePicker().pickImage(source: ImageSource.gallery);
          file = File(_image!.path);
          firebase_storage.Reference _refPath = firebase_storage
              .FirebaseStorage.instance
              .ref()
              .child('MyImageRepo')
              .child(_auth.currentUser!.uid);
          firebase_storage.UploadTask _uploadTask = _refPath.putFile(file!);

          String _url = await (await _uploadTask).ref.getDownloadURL();
          staticImagePath = _url.toString();

          await _propertiesCollection.doc(_auth.currentUser!.uid).update(({
                'postId': staticImagePath,
              }));

        } catch (e) {
          return Center(child: Text(e.toString()));
        }

  }