【问题标题】:How to get URL from Firebase Storage getDownloadURL如何从 Firebase 存储 getDownloadURL 获取 URL
【发布时间】:2020-06-28 01:11:00
【问题描述】:

我正在尝试获取指向 Firebase 存储桶中文件的“长期持久下载链接”。 我已将其权限更改为

service firebase.storage {
  match /b/project-xxx.appspot.com/o {
    match /{allPaths=**} {
      allow read, write;
    }
  }
}

我的 javacode 看起来像这样:

private String niceLink (String date){
    String link;
    // Points to the root reference
    StorageReference storageRef = FirebaseStorage.getInstance().getReference();
    StorageReference dateRef = storageRef.child("/" + date+ ".csv");
    link = dateRef.getDownloadUrl().toString();
    return link;
}

当我运行它时,我得到的 uri 链接看起来像 com.google.android.gms.tasks.zzh@xxx

问题 1. 我可以从这里获得类似于以下内容的下载链接:https://firebasestorage.googleapis.com/v0/b/project-xxxx.appspot.com/o/20-5-2016.csv?alt=media&token=b5d45a7f-3ab7-4f9b-b661-3a2187adxxxx

在尝试获取上面的链接时,我更改了返回前的最后一行,如下所示:

private String niceLink (String date){
    String link;
    // Points to the root reference
    StorageReference storageRef = FirebaseStorage.getInstance().getReference();
    StorageReference dateRef = storageRef.child("/" + date+ ".csv");
    link = dateRef.getDownloadUrl().getResult().toString();
    return link;
}

但是当我这样做时,我得到一个 403 错误,并且应用程序崩溃了。控制台告诉我这是 bc 用户未登录 /auth。 "请先登录,然后再索取令牌"

问题 2。我该如何解决这个问题?

【问题讨论】:

    标签: java android firebase firebase-storage


    【解决方案1】:

    请参考documentation for getting a download URL

    当您调用getDownloadUrl() 时,调用是异步的,您必须订阅成功回调才能获得结果:

    // Calls the server to securely obtain an unguessable download Url
    private void getUrlAsync (String date){
        // Points to the root reference
        StorageReference storageRef = FirebaseStorage.getInstance().getReference();
        StorageReference dateRef = storageRef.child("/" + date+ ".csv");
        dateRef.getDownloadUrl().addOnSuccessListener(new OnSuccessListener<Uri>()
        {
            @Override
            public void onSuccess(Uri downloadUrl) 
            {                
               //do something with downloadurl
            } 
        });
    }
    

    这将返回一个公开的不可猜测的下载 url。如果你刚刚上传了一个文件,这个公开的url会在上传成功回调中(上传后不需要调用其他异步方法)。

    但是,如果您想要的只是引用的 String 表示,您可以调用 .toString()

    // Returns a Uri of the form gs://bucket/path that can be used
    // in future calls to getReferenceFromUrl to perform additional
    // actions
    private String niceRefLink (String date){
        // Points to the root reference
        StorageReference storageRef = FirebaseStorage.getInstance().getReference();
        StorageReference dateRef = storageRef.child("/" + date+ ".csv");
        return dateRef.toString();
    }
    

    【讨论】:

    • 使用异步我似乎也遇到了 .addSuccessListener 错误(无法解析方法)。此外,当我在 onSuccess 方法中使用类似 link = downloadUrl.toString() 时,它说它需要是最终的。任何进一步的帮助都会很棒!
    • 1.对不起,那应该是 addOnSuccessListener (typo) 2. 当你在 java 中得到一个错误“needs to be final”时,这意味着有一个闭包问题。请参阅stackoverflow.com/questions/1299837/… 了解更多信息。基本上,简短的回答是,将“链接”变量定义为类成员,它应该没问题。
    • 经过一些编辑后工作起来就像一个沙姆!感谢您的帮助!
    【解决方案2】:

    //Firebase 存储 - 轻松处理上传和下载。

    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable final Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if(requestCode == RC_SIGN_IN){
            if(resultCode == RESULT_OK){
                Toast.makeText(this,"Signed in!", LENGTH_SHORT).show();
            } else if(resultCode == RESULT_CANCELED){
                Toast.makeText(this,"Signed in canceled!", LENGTH_SHORT).show();
                finish();
            }
        } else if(requestCode == RC_PHOTO_PICKER && resultCode == RESULT_OK){
    
            // HERE I CALLED THAT METHOD
            uploadPhotoInFirebase(data);
    
        }
    }
    
    private void uploadPhotoInFirebase(@Nullable Intent data) {
        Uri selectedImageUri = data.getData();
    
        // Get a reference to store file at chat_photos/<FILENAME>
        final StorageReference photoRef = mChatPhotoStorageReference
                        .child(selectedImageUri
                        .getLastPathSegment());
    
        // Upload file to Firebase Storage
        photoRef.putFile(selectedImageUri)
                .addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
                    @Override
                    public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
    
                        // Download file From Firebase Storage
                        photoRef.getDownloadUrl().addOnSuccessListener(new OnSuccessListener<Uri>() {
                            @Override
                            public void onSuccess(Uri downloadPhotoUrl) {
                                //Now play with downloadPhotoUrl
                                //Store data into Firebase Realtime Database
                                FriendlyMessage friendlyMessage = new FriendlyMessage
                                        (null, mUsername, downloadPhotoUrl.toString());
                                mDatabaseReference.push().setValue(friendlyMessage);
                            }
                        });
                    }
                });
    }
    

    【讨论】:

      【解决方案3】:

      这里我正在同时上传和获取图片网址...

                 final StorageReference profileImageRef = FirebaseStorage.getInstance().getReference("profilepics/" + System.currentTimeMillis() + ".jpg");
      
                  if (uriProfileImage != null) {
      
                  profileImageRef.putFile(uriProfileImage)
                              .addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
                                  @Override
                                  public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
                                     // profileImageUrl taskSnapshot.getDownloadUrl().toString(); //this is depreciated
      
                                //this is the new way to do it
                         profileImageRef.getDownloadUrl().addOnCompleteListener(new OnCompleteListener<Uri>() {
                                          @Override
                                          public void onComplete(@NonNull Task<Uri> task) {
                                             String profileImageUrl=task.getResult().toString();
                                              Log.i("URL",profileImageUrl);
                                          }
                                      });
                                  }
                              })
                              .addOnFailureListener(new OnFailureListener() {
                                  @Override
                                  public void onFailure(@NonNull Exception e) {
                                      progressBar.setVisibility(View.GONE);
                                      Toast.makeText(ProfileActivity.this, "aaa "+e.getMessage(), Toast.LENGTH_SHORT).show();
                                  }
                              });
                  }
      

      【讨论】:

      • 你可以使用这个 URL 向使用 glide 库的用户显示图像吗?
      【解决方案4】:

      对我来说,我在 Kotlin 中编写了代码,但遇到了同样的错误“getDownload()”。以下是对我有用的依赖项和 Kotlin 代码。

      implementation 'com.google.firebase:firebase-storage:18.1.0'firebase 存储依赖项

      这是我添加的,它在 Kotlin 中对我有用。 Storage() 会在 Download() 之前出现

      profileImageUri = taskSnapshot.storage.downloadUrl.toString()
      

      【讨论】:

        【解决方案5】:
        StorageReference mStorageRef = FirebaseStorage.getInstance().getReference();
        
        final   StorageReference fileupload=mStorageRef.child("Photos").child(fileUri.getLastPathSegment());
        UploadTask uploadTask = fileupload.putFile(fileUri);
        
        Task<Uri> urlTask = uploadTask.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();
                }
                return ref.getDownloadUrl();
        
            }
            }).addOnCompleteListener(new OnCompleteListener<Uri>() {
                @Override
                public void onComplete(@NonNull Task<Uri> task) {
                    if (task.isSuccessful()) {
                        Uri downloadUri = task.getResult();
                        Picasso.get().load(downloadUri.toString()).into(image);
        
                    } else {
                         // Handle failures
                    }
               }
        });
        

        【讨论】:

          【解决方案6】:
          Clean And Simple
          private void putImageInStorage(StorageReference storageReference, Uri uri, final String key) {
                  storageReference.putFile(uri).addOnCompleteListener(MainActivity.this,
                          new OnCompleteListener<UploadTask.TaskSnapshot>() {
                              @Override
                              public void onComplete(@NonNull Task<UploadTask.TaskSnapshot> task) {
                                  if (task.isSuccessful()) {
                                      task.getResult().getMetadata().getReference().getDownloadUrl()
                                              .addOnCompleteListener(MainActivity.this, 
                                                      new OnCompleteListener<Uri>() {
                                          @Override
                                          public void onComplete(@NonNull Task<Uri> task) {
                                              if (task.isSuccessful()) {
                                                  FriendlyMessage friendlyMessage =
                                                          new FriendlyMessage(null, mUsername, mPhotoUrl,
                                                                  task.getResult().toString());
                                                  mFirebaseDatabaseReference.child(MESSAGES_CHILD).child(key)
                                                          .setValue(friendlyMessage);
                                              }
                                          }
                                      });
                                  } else {
                                      Log.w(TAG, "Image upload task was not successful.",
                                              task.getException());
                                  }
                              }
                          });
              }
          

          【讨论】:

            【解决方案7】:

            getDownloadUrl 方法现已在新的 Firebase 更新中被弃用。而是使用以下方法。 taskSnapshot.getMetadata().getReference().getDownloadUrl().toString()

            【讨论】:

            • 输出是这样的:com.google.android.gms.tasks.zzu@ed93411
            【解决方案8】:

            将收到的 URI 更改为 URL

             val urlTask = uploadTask.continueWith { task ->
                        if (!task.isSuccessful) {
                            task.exception?.let {
                                throw it
                            }
                        }
            
            
                        spcaeRef.downloadUrl
                    }.addOnCompleteListener { task ->
                        if (task.isSuccessful) {
            
                            val downloadUri = task.result
            
                            //URL
                            val url = downloadUri!!.result
            
                        } else {
                            //handle failure here
                        }
                    }
            
            

            【讨论】:

              【解决方案9】:

              您可以将图片上传到 Firestore 并通过以下函数获取其下载 URL:

                Future<String> uploadPic(File _image) async {
              
                  String fileName = basename(_image.path);
                  StorageReference firebaseStorageRef = FirebaseStorage.instance.ref().child(fileName);
                  StorageUploadTask uploadTask = firebaseStorageRef.putFile(_image);
                  var downloadURL = await(await uploadTask.onComplete).ref.getDownloadURL();
                  var url =downloadURL.toString();
              
                 return url;
              
                }
              

              【讨论】:

                【解决方案10】:

                【讨论】:

                • 欢迎来到 StackOverflow @AugCode!回答问题时,请确保包含实际答案,而不是没有上下文的链接。链接到您的资源并指向进一步的研究很有用,但一个好的答案将包含您的发现摘要,这可以帮助提问者。更多详情请查看stackoverflow.com/help/how-to-answer
                【解决方案11】:

                您也可以在最新的 Firebase_storage 版本 nullsafe 中执行以下操作,

                //Import
                import 'package:firebase_storage/firebase_storage.dart' as firebase_storage;
                
                Future<void> _downloadLink(firebase_storage.Reference ref) async {
                    //Getting link make sure call await to make sure this function returned a value
                    final link = await ref.getDownloadURL();
                
                    await Clipboard.setData(ClipboardData(
                      text: link,
                    ));
                
                    ScaffoldMessenger.of(context).showSnackBar(
                      const SnackBar(
                        content: Text(
                          'Success!\n Copied download URL to Clipboard!',
                        ),
                      ),
                    );
                  }
                

                【讨论】:

                  【解决方案12】:
                  implementation 'com.google.firebase:firebase-storage:19.2.0'
                  

                  最近从上传任务中获取 url 不起作用,所以我尝试了这个并在上述依赖项上为我工作。 所以在你使用firebase上传方法的地方使用这个。 filepath 是 Firebase 存储的引用。

                  filePath.putFile(imageUri).addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
                      @Override
                      public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
                          filePath.getDownloadUrl().addOnSuccessListener(new OnSuccessListener<Uri>() {
                              @Override
                              public void onSuccess(Uri uri) {
                                  Log.d(TAG, "onSuccess: uri= "+ uri.toString());
                              }
                          });
                      }
                  });
                  

                  【讨论】:

                    【解决方案13】:

                    在大于 11.0.5 的 Firebase 版本中删除了 getDownloadUrl 方法 我建议使用仍然使用此方法的 11.0.2 版本。

                    【讨论】:

                      【解决方案14】:
                       private void getDownloadUrl(){
                              FirebaseStorage storage     = FirebaseStorage.getInstance();
                              StorageReference storageRef = storage.getReference();
                              StorageReference imageRef   = storageRef.child("image.jpg");
                              imageRef.getDownloadUrl().addOnCompleteListener(new OnCompleteListener<Uri>() {
                                  @Override
                                  public void onComplete(@NonNull Task<Uri> task) {
                                      String profileimageurl =task.getResult().toString();
                                      Log.e("URL",profileimageurl);
                                      ShowPathTextView.setText(profileimageurl);
                                  }
                              });
                          }
                      

                      【讨论】:

                        猜你喜欢
                        • 2019-05-03
                        相关资源
                        最近更新 更多