【问题标题】:Firebase storage wait for listenersFirebase 存储等待侦听器
【发布时间】:2020-05-16 03:21:27
【问题描述】:

我有一个函数(不在活动内),它将图像上传到 Firebase 存储并返回 URL。 我的问题是,我需要等待 UploadTask 完成,否则它会返回一个空字符串。 .

 public String pushRegisterImage(Bitmap image) {
    StorageReference imagesRef = storage.getReferenceFromUrl(STORAGE_REF)
            .child(FINDMYPET).child(IMAGES).child(String.valueOf(UUID.randomUUID()));
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    image.compress(Bitmap.CompressFormat.JPEG, 100, baos);
    byte[] data = baos.toByteArray();
    UploadTask uploadTask = imagesRef.putBytes(data);

    uploadTask.addOnFailureListener(new OnFailureListener() {
        @Override
        public void onFailure(@NonNull Exception e) {
            imageUrl = null;
            Log.e(LOG_TAG, "Image upload error: " + e);
        }
    }).addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
        @Override
        public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
            imageUrl = taskSnapshot.getDownloadUrl().toString();
            Log.v(LOG_TAG, "Image uploade sucess, url: " + imageUrl);
        }
    });
    return imageUrl;
}

【问题讨论】:

    标签: android task firebase-storage


    【解决方案1】:

    我遇到了同样的问题:最适合我的解决方案是使用 WorkManagerCountDownLatch

    这是代码中的一个 sn-p,它为我完成了这项工作。这里的日志来自Timber。它在任务完成后但在工作人员返回成功之前以字符串的形式从 Firebase 中返回 downloadUrl。

        @NonNull
        @Override
        public Result doWork() {
            mFirebaseStorage = mFirebaseStorage.getInstance();
            mTriviaImageStorageReference = mFirebaseStorage.getReference().child("images");
    
            CountDownLatch countDown = new CountDownLatch(2);
            Uri imageUri = Uri.parse(getInputData().getString(KEY_IMAGE_URI));
    
            try {
    
            // get the image reference
            final StorageReference imageRef = mTriviaImageStorageReference.child(imageUri.getLastPathSegment());
    
            // upload the image to Firebase
            imageRef.putFile(imageUri).continueWithTask(new Continuation<UploadTask.TaskSnapshot, Task<Uri>>() {
                @Override
                public Task<Uri> then(@NonNull Task<UploadTask.TaskSnapshot> task) throws Exception {
                    if (!task.isSuccessful()) {
                        throw task.getException();
                    }
                    countDown.countDown();
                    return imageRef.getDownloadUrl();
                }
            }).addOnCompleteListener(new OnCompleteListener<Uri>() {
                @Override
                public void onComplete(@NonNull Task<Uri> task) {
                    if (task.isSuccessful()) {
                        Timber.d("Image was successfully uploaded to Firebase");
                        Uri downloadUri = task.getResult();
                        String imageUrl = downloadUri.toString();
    
                        Timber.d(("URl of the image is: " + imageUrl));
    
                        mOutputData = new Data.Builder()
                                .putString(KEY_FIREBASE_IMAGE_URL, imageUrl)
                                .build();
                        countDown.countDown();
                    } else {
                        Toast.makeText(getApplicationContext(), "upload failed", Toast.LENGTH_SHORT).show();
                        countDown.countDown();
                    }
                }
            });
            countDown.await();
            return Result.success(mOutputData);
    
            } catch (Throwable throwable) {
                Timber.e(throwable, "Error uploading image");
                return Result.failure();
            }
        }

    【讨论】:

      【解决方案2】:

      使用此处提到的com.google.android.gms.tasks.Tasks.await(uploadTask);Firebase Storage upload synchronously。这解决了我的问题(我需要一个接一个上传更多文件)。另外,这不打算在 UIThread 上运行,所以做一个异步任务或类似的东西。

      final UploadTask uploadTask 
                  =FirebaseStorage.getInstance().getReference("...").putFile(path);
      try {
          com.google.android.gms.tasks.Tasks.await(uploadTask);
      } catch (ExecutionException e) {
          e.printStackTrace();
      } catch (InterruptedException e) {
          e.printStackTrace();
      }
      Log.d("Upload", "upload took " + (System.currentTimeMillis() - start));
      

      【讨论】:

        【解决方案3】:

        您正在尝试将数据同步放入 Firebase(并等待结果),但 Android SDK 提供的与 Firebase 数据库的所有交互都是异步的(它是一个实时数据库,不适合“同步”事物)所以有无法解决您的退货问题。

        因此,对您的问题的回答是重新考虑您的代码,并记住 Firebase 的一切都是异步

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2023-03-28
          • 1970-01-01
          • 2021-08-02
          • 2015-11-06
          • 2017-09-09
          • 2017-02-22
          • 1970-01-01
          • 2020-04-12
          相关资源
          最近更新 更多