将 Firebase 存储下载 URL 推送到 Firebase 云 Firestore

Posted

技术标签:

【中文标题】将 Firebase 存储下载 URL 推送到 Firebase 云 Firestore【英文标题】:Pushing Firebase storage download URLs to Firebase cloud Firestore 【发布时间】:2019-11-15 04:44:30 【问题描述】:

如何将 Firebase 存储文件的下载 URL 推送到 Firestore 云?我有一个项目可以将 PDF 文件上传到 Firestore 存储,但我无法将上传文件的下载 URL 推送到 Firestore 云。

我需要捕获每个文件的上传 URL 并将其发送到 firestore 中的文档以便能够下载它。我正在上传和下载 PDF 文件。

这是我的代码:

public class pdfUploader extends AppCompatActivity 
    private StorageReference mStorageRef;
    Button upload;
    Button select;
    int CODE=215;
    private CollectionReference dbFirestore;

    @Override
    protected void onCreate(Bundle savedInstanceState) 
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_pdf_uploader);
        mStorageRef = FirebaseStorage.getInstance().getReference();
        upload = findViewById(R.id.upload);
        select = findViewById(R.id.choose);
        select.setOnClickListener(new View.OnClickListener() 
            @Override
            public void onClick(View v) 
                selectFile();
            
        );
    

    public void selectFile () 
        Intent i = new Intent(Intent.ACTION_GET_CONTENT);
        i.setType("*/*");
        startActivityForResult(Intent.createChooser(i,"Select a file"), CODE);
    

    protected void onActivityResult(int requestCode, int resultCode, Intent data) 
        String filePath = data.getDataString();
        Uri SelectedFileLocation=Uri.parse(filePath);
        UploadFile(SelectedFileLocation);
        super.onActivityResult(requestCode, resultCode, data);
    

    public  void UploadFile( Uri file) 
        Toast.makeText(this, "Please wait.. the file is uploading!", Toast.LENGTH_SHORT).show();
        //Uri file = Uri.fromFile(new File("path/to/images/rivers.jpg"));
        StorageReference riversRef = mStorageRef.child(Objects.requireNonNull(file.getLastPathSegment()));
        riversRef.putFile(file)
            .addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() 
                @Override
                public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) 
                    Toast.makeText(pdfUploader.this, "Upload Success", Toast.LENGTH_SHORT).show();
                
            ).addOnFailureListener(new OnFailureListener() 
                @Override
                public void onFailure(@NonNull Exception exception) 
                    Toast.makeText(pdfUploader.this, "Upload Failed", Toast.LENGTH_SHORT).show();

                
            );
    

【问题讨论】:

【参考方案1】:

将此变量分配在顶部

FirebaseFirestore db;

//In oncreateView we have to assign now db so.
db = FirebaseFirestore.getInstance();

获取文件 uri 的代码:

riversRef.putFile(File).addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() 
    @Override
    public void onSuccess(UploadTask.TaskSnapshot taskSnapshot)
    
        riversRef.getDownloadUrl().addOnSuccessListener(new OnSuccessListener<Uri>() 
                @Override
                public void onSuccess(Uri uri) 
                    Uri downloadUrl = uri;
                    Toast.makeText(MtActivity.this, "Upload Done", Toast.LENGTH_LONG).show();   
                    //After upload Complete we have to store the Data to firestore.
                    Map<String, Object> file = new HashMap<>();
                    file.put("url", downloadUrl.toString()); // We are using it as String because our data type in Firestore will be String
                    db.collection("/*Put you're collection name*/").document("/*And Document name Here*/")
                            .set(file)
                            .addOnSuccessListener(new OnSuccessListener<Void>() 
                                @Override
                                public void onSuccess(Void aVoid) 
                                    Log.d(TAG, "DocumentSnapshot successfully written!");
                                
                            )
                            .addOnFailureListener(new OnFailureListener() 
                                @Override
                                public void onFailure(@NonNull Exception e) 
                                    Log.w(TAG, "Error writing document", e);
                                
                            );
                
    
);

如果下载 url 过期,有更好的方法将您的图像文件存储在您的存储和 Firestore 中

代码:

riversRef.putFile(file)
                .addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() 
                    @Override
                    public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) 
                        String path = //Put path of storage it will be something like [images/filename.jpg(Put your extension of file)] this path from firebase storage
                        Map<String, Object> file = new HashMap<>();
                        file.put("url", path); // We are using it as String because our data type in Firestore will be String
                        db.collection("/*Put you're collection name*/").document("/*And Document id Here*/")
                                .set(file)
                                .addOnSuccessListener(new OnSuccessListener<Void>() 
                                    @Override
                                    public void onSuccess(Void aVoid) 
                                        Log.d(TAG, "DocumentSnapshot successfully written!");
                                    
                                )
                                .addOnFailureListener(new OnFailureListener() 
                                    @Override
                                    public void onFailure(@NonNull Exception e) 
                                        Log.w(TAG, "Error writing document", e);
                                    
                                );
                    
                )
                .addOnFailureListener(new OnFailureListener() 
                    @Override
                    public void onFailure(@NonNull Exception exception) 
                        Toast.makeText(pdfUploader.this, "Upload Failed", Toast.LENGTH_SHORT).show();

                    
                );

当您处理图像时,上面的代码会更好用,请阅读docs 了解更多详情

【讨论】:

我有另一个想法,如果你愿意,最好上传带有文档 ID 的文件 谢谢,运行在无法解析符号 'filepath' 的问题中,当创建局部变量时它会说在空对象上运行,我在 biggner 级别 sry for selly quastions 另外,我想保留自动生成的文档名称 已解决!你的回答是绝对正确的,我通过添加:- \\ Task downloadUrl = taskSnapshot.getStorage().getDownloadUrl(); . 请务必记住,当您存储 Firebase 存储 URL 时,它们可能包含过期的身份验证令牌。最好也保存文件的 ID,这样当 URL 过期时,您可以再次调用 getDownloadUrl() 来刷新 URL。在正常操作中,令牌不应过期,但您可以从 Firebase 控制台使下载 URL 中的所有令牌失效,因此无论如何您最好做好准备。

以上是关于将 Firebase 存储下载 URL 推送到 Firebase 云 Firestore的主要内容,如果未能解决你的问题,请参考以下文章

Vuejs + Firebase Storage 将多个图像上传到 Firebase Storage 并将所有 downloadURL 推送到 Firestore

使用子参考值将数据推送到 Firebase

实时数据库未将数据推送到 Firebase

Firebase 上传未获取下载 URL

将对象推送到 Firebase 的智能方法

将 Firebase 值推送到下拉菜单