Добавление изображения в Firebase Storage и его ссылки в Firestore, избегая двойной записи в Firestore - PullRequest
0 голосов
/ 19 ноября 2018

Я хочу добавить изображение (сгенерированного пользователем поста) в Firebase Storage и его URL в Firestore DB.Но изображений может быть много, поэтому я хочу хранить их в папках в хранилище.

Таким образом, путь хранения выглядит следующим образом:

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

Здесь postId - этоссылка на документ Идентификатор новой публикации, которую я добавляю в Firestore.Но поскольку firestore не поддерживает пустой документ, использующий API .add(), мне нужно написать фиктивную опцию, просто чтобы получить идентификатор документа (который является postId)

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

Теперь я использую этот postId в пути хранения и загрузить изображение.

Когда загрузка будет завершена, я получу ее URL-адрес для загрузки (getDownloadURL()), который я хочу сохранить в БД Firestore.Поэтому мне пришлось инициировать еще одну запись в тот же документ и обновить ее с помощью URL-адреса загрузки образа.

postDocRef.update({ url : storageDownloadUrl })

Весь этот процесс вызывает две операции записи в Firestore.

Есть ли лучший способ, который может привести к одиночной записи в Firestore.

Несколько вариантов, которые я подумал:

  1. Сгенерировать postId локально самостоятельно, это будетвыступать в качестве идентификатора документа, а также.[ Предлагает ли хранилище Firebase уникальные идентификаторы файлов?
  2. Не используйте postId в пути хранения, вместо этого генерируйте уникальное изображение. Name
  3. Firestore рассматривает возможность предоставления ссылки на пустые документы, как в реальном времени БД [ Эквивалент .push в Firestore?

Ответы [ 2 ]

0 голосов
/ 19 ноября 2018

Попробуйте эту логику, она может где-то помочь:

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);
                }
            })
0 голосов
/ 19 ноября 2018

Вам не нужна «фиктивная запись», чтобы получить уникальный сгенерированный идентификатор документа. Вы можете просто использовать метод doc () без параметров , чтобы сгенерировать DocumentReference с уникальным идентификатором, а затем использовать его для записи всего документа через некоторое время, когда данные будут готовы. Эти уникальные идентификаторы всегда генерируются синхронно на клиенте.

...