1

I want to add an Image (of a user generated post) in Firebase Storage, and its url in the Firestore DB. But there can be a lot of images, so i want to keep them in folders in Storage.

So the storage path looks like this:

/${uid}/posts/${postId}/${image1.name}

Here the postId is the document reference Id of a new Post that i add in Firestore. But since firestore does not support empty doc using the .add() api, I have to a dummy write op, just to get the doc ref Id (which is postId)

db.collection('posts').add({isExist: true})
.then(docRef => { postDocRef = docRef; postId = docRef.id } )

Now i use this postId in the storage path, and upload the image.

Once the upload is done, I receive its download url (getDownloadURL()), which i want to store in the Firestore DB. So i had to trigger another write to the same doc and update it with the image download url.

postDocRef.update({ url : storageDownloadUrl })

This whole process causes two write ops to the Firestore.

Is there a better way that can result in single write to Firestore.

Few option that i thought:

  1. Generate postId locally on my own, that will act as document Id as well. [Does Firebase storage offer unique Id's for files?
  2. Do not use postId in the storage path, instead generate unique image.name
  3. Firestore considers providing reference to empty docs, like in realtime DB [Equivalent of .push in Firestore?
Doug Stevenson
  • 297,357
  • 32
  • 422
  • 441
kernelman
  • 992
  • 1
  • 13
  • 28

2 Answers2

2

You don't need a "dummy write" to get a unique generated document ID. You can simply use the doc() method with no parameters to generate a DocumentReference with a unique id, then use that to write the entire document some time later when the data is ready. Those unique IDs are always generated synchronously on the client.

Doug Stevenson
  • 297,357
  • 32
  • 422
  • 441
1

Try this logic, it might help somewhere:

final Uri uri = data.getData();
//From the onActivityResult(int requestCode, int resultCode, Intent data) method

StorageReference storageReference = YOUR_PAPER_STORAGE_REF;

// Create the file metadata
StorageMetadata metadata = new StorageMetadata.Builder()
    .setContentType("application/pdf").build();

storageReference.putFile(uri, metadata)
.continueWithTask(new Continuation<UploadTask.TaskSnapshot, Task<Uri>>() {
                @Override
                public Task<Uri> then(@NonNull Task<UploadTask.TaskSnapshot> task) throws Exception {
                    // Forward any exceptions
                    if (!task.isSuccessful()) {
                        throw Objects.requireNonNull(task.getException());
                    }

                    // Request the public download URL
                    return storageReference.getDownloadUrl();
                }
            })
.addOnSuccessListener(new OnSuccessListener<Uri>() {
                @Override
                public void onSuccess(@NonNull Uri downloadUri) {

                    PaperPost mPaperPost = new PaperPost(mFirebaseUser, downloadUri.toString());

                    final DocumentReference mPPPostRef = mFirestore.collection("tblPapers").document().set(mPaperPost);
                }
            })
Joseph Wambura
  • 2,732
  • 2
  • 21
  • 24