Получить несколько URL для загрузки из хранилища Firebase и сохранить их в Firebase FireStore - PullRequest
0 голосов
/ 15 мая 2019

Я успешно загрузил несколько выбранных аудиофайлов в хранилище Firebase, и я могу получить URL-адреса для всех из них. Так как мне нужно загрузить несколько файлов, я использовал цикл для этого. После загрузки файлов и получения URL-адресов, я хочу сохранить их в FireStore, и вот что я сделал для этого.

Функция для загрузки файлов

private void uploadAudioFiles(List<Uri> list, final Map<String, String> hashMap) {
        if (list.size() > 0){
            for (int a=0; a<list.size(); a++){
                Uri perFile = list.get(a);
                String filename = getSelectedFileName(perFile);
                final StorageReference audioFileReference = referenceFolder.child("audioClipData/"+filename);
                final int finalA = a;
                audioFileReference.putFile(perFile).addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
                    @Override
                    public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
                        audioFileReference.getDownloadUrl().addOnSuccessListener(new OnSuccessListener<Uri>() {
                            @Override
                            public void onSuccess(Uri uri) {
                                hashMap.put("audioFile"+ finalA, String.valueOf(uri));
                                Log.e("APP_LOG:HashMap(AudioA)", String.valueOf(hashMap));
                            }
                        });
                    }
                });
            }
        }
    }

При нажатии кнопки сохранения

Ниже приведен код, который вызывает функцию uploadAudioFiles ().

Map<String, String> hashMap = new HashMap<>();
    String username = name.getText().toString();
            if (!username.isEmpty()){
                progressDialog.show();
                hashMap.put("username", username);
                uploadAudioFiles(audioClipList, hashMap);


                Log.e("APP_LOG:HashMapFINAL", hashMap.toString());
                firestore.collection(currentUser.getUid()).add(hashMap).addOnSuccessListener(new OnSuccessListener<DocumentReference>() {
                    @Override
                    public void onSuccess(DocumentReference documentReference) {
                        progressDialog.dismiss();
                    }
                });
            }else {
                name.setError("Required");
            }

Вот журнал, который я получаю, когда нахожусь в функции uploadAudioFiles ()

E / APP_LOG: HashMap (AudioA): {username = Abhi, audioFile0 = https://firebasestorage.googleapis.com/v0/b/myapp.appspot.com/o/linktofile}

Вот журнал, который я получаю, когда я нахожусь вне функции uploadAudioFiles () (ButtonClick)

E / APP_LOG: HashMapFINAL: {username = Abhi}

Теперь я не могу понять, почему HashMap отличается, когда я нахожусь в функции uploadfile и когда я нахожусь вне функции uploadfile. Это из-за объема цикла for или что-то еще?

Может кто-нибудь помочь мне разобраться в ситуации и разрешить ситуацию?

Ответы [ 2 ]

0 голосов
/ 19 мая 2019

Вот новый код, чтобы делать то, что я хочу!

private void executeUpload(final Map<String, String> hashMap, final List<Uri> uriList) {
        if (uriList.size() > 0){
            spotDialog.show();
                int counter = 0;
                final String firebasePushID = firestore.collection(currentUser.getUid()).document().getId();
                for (int i=0;i<uriList.size(); i++){
                    Uri perFile = uriList.get(i);
                    counter++;
                    final int finalCounter = counter;
                    final int finalI = i;
                    storageReference.child(firebasePushID).putFile(perFile).addOnCompleteListener(new OnCompleteListener<UploadTask.TaskSnapshot>() {
                        @Override
                        public void onComplete(@NonNull Task<UploadTask.TaskSnapshot> task) {
                            if (task.isSuccessful()){
                                storageReference.child(firebasePushID).getDownloadUrl().addOnCompleteListener(new OnCompleteListener<Uri>() {
                                    @Override
                                    public void onComplete(@NonNull Task<Uri> task) {
                                        if (task.isSuccessful()){
                                            String uri = String.valueOf(task.getResult());
                                            Log.e(LOGCODE, uri);
                                            hashMap.put(fileName, uri);
                                            if (!(finalCounter < uriList.size())){
                                                firestore.collection(currentUser.getUid()).add(hashMap).addOnCompleteListener(new OnCompleteListener<DocumentReference>() {
                                                    @Override
                                                    public void onComplete(@NonNull Task<DocumentReference> task) {
                                                        if (task.isSuccessful()){
                                                            clearFormData();
                                                            spotDialog.dismiss();
                                                            Log.e(LOGCODE, hashMap.toString());
                                                            Toast.makeText(MainActivity.this, "Saved data successfully.", Toast.LENGTH_SHORT).show();
                                                        }else {
                                                            Log.e(LOGCODE, Objects.requireNonNull(task.getException()).getMessage());
                                                            spotDialog.dismiss();
                                                            Toast.makeText(MainActivity.this, "Couldn't save data! Data seems to be lost in space :(", Toast.LENGTH_SHORT).show();
                                                        }
                                                    }
                                                });
                                            }
                                        }else {
                                            spotDialog.dismiss();
                                            Log.e(LOGCODE, Objects.requireNonNull(task.getException()).getMessage());
                                            Toast.makeText(MainActivity.this," File uploaded but lost in space :(", Toast.LENGTH_SHORT).show();
                                        }
                                    }
                                });
                            }else{
                                spotDialog.dismiss();
                                Log.e(LOGCODE, Objects.requireNonNull(task.getException()).getMessage());
                                Toast.makeText(AddTransaction.this, "Couldn't upload file ", Toast.LENGTH_SHORT).show();
                            }
                        }
                    });
                }
        }
    }

Что я хотел сделать?

Сначала добавьте имя пользователя в hashmap, затем uploadAudioFiles, затем сохраните URL-адрес этих файлов в hashmap, а затем сохраните его в firestore.

Проблема со старым кодом?

старый код был написан для хранения аудиофайлов в FirebaseStorage, а затем для сохранения его URL в firestore, но, к сожалению, со старым кодом этого не произошло.

Причина проблемы : - API-интерфейсы Firebase являются асинхронными, и чтобы все работало должным образом по порядку, мне нужно подождать, пока все файлы будут загружены, а его URL-адрес сохранен в hashmap. Поскольку мой код не был написан для ожидания чего-либо, он просто вызывал функцию «uploadAudioFiles», а затем, не дожидаясь ответа, раньше достигал конца функции. Это было причиной, почему мой хэш-карта была пуста Файлы не были загружены до тех пор, пока я не попытался сохранить хэш-карту в firestore, поэтому хэш-карта была пуста.

Как я решил свою проблему?

В старом коде я вызывал uploadAudioFunction, которая использовалась для загрузки файлов в FirebaseStorage, но она не была написана для сохранения hashmap в firestore. Итак, я в основном переписываю функцию для обработки загрузки файлов, а также для обработки сохранения hashmap в firestore. Я использовал переменную counter для подсчета, если цикл for вращался до конца моего списка. Используя эту переменную-счетчик, я написал условие if ... else, которое говорит, что если цикл вращался требуемое время, затем сохраните данные hashmap в firetore. Таким образом, я могу ждать, пока все файлы будут загружены и их URL сохранены в хэш-карту.

Предупреждение: - Это не лучший подход. Иногда hashmap не включите последний URL файла, но файл успешно загружен. Это все, что у меня есть на данный момент, но я все еще пытаюсь найти новый и эффективный способ сделать это. Если у вас есть лучший подход, пожалуйста, скажите мне.

0 голосов
/ 15 мая 2019

API Firebase являются асинхронными и возвращаются непосредственно перед завершением работы.Ваш HashMap будет меняться с течением времени, когда загрузка завершена и URL-адреса загрузки известны.Если вы хотите знать, когда все загрузки завершены, и все URL-адреса загрузки известны, вам нужно обратить внимание на объекты Task, возвращаемые всеми из них.Прямо сейчас ваша функция uploadAudioFiles просто немедленно вернется, до того, как какая-либо работа будет завершена, и код, который запускается после нее, не увидит никаких результатов до некоторого времени спустя.

...