如何在单个事务中将图像上传到 Firebase 存储并在数据库中保存参考?

Posted

技术标签:

【中文标题】如何在单个事务中将图像上传到 Firebase 存储并在数据库中保存参考?【英文标题】:How to upload image to firebase storage and save reference in the database in single transaction? 【发布时间】:2018-04-11 06:18:25 【问题描述】:

我想将图像上传到 firebase 存储并将其链接保存在 firebase 数据库中。无论出于何种原因,保存到数据库的链接都可能失败,然后我在存储中有未使用的、未链接的图像。是否有可能以某种方式确保在上传图像链接后将其保存在数据库中?

【问题讨论】:

【参考方案1】:

这个模式怎么样。

    将文件保存在具有 1 天生命周期的存储桶中的云存储中。我们可以称之为时间桶。 将网址保存到您的数据库中。 有一个云功能,可以将对象从临时存储桶移动到永久存储桶。一旦对象在永久存储桶中,该函数可以替换数据库中的 url。

因此,如果您无法将 url 保存到数据库中,则该对象将在 1 天后被删除

【讨论】:

【参考方案2】:

是的,您可以像这样在您的任务中使用addOnSuccessListener

uploadTask.addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() 
    @Override
    public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) 
        Uri downloadUrl = taskSnapshot.getDownloadUrl();
        firebaseRef.child("urls").child("urlId1").setValue(downloadUrl.toString);
    
);

这意味着只有当上传成功时,你才会将 url 写入数据库。

【讨论】:

我的问题不同。它是“仅将图像与数据库更新一起上传”。所以要么都成功,要么都失败。 这就是为什么你需要做2个单独的操作。这不是你要的吗?如果上传失败,则不会将任何内容写入数据库,如果上传成功,则只会将 url 写入数据库。如果在写数据的时候也可以使用addOnCompleteListener() 上传可以成功,然后无论出于何种原因(比如用户关闭浏览器),都没有将 url 写入数据库,并且您的存储中有没有在任何地方引用的图像。 @AlexMamo 但它可能会成功上传图片,但未能更新 Firestore 中的数据,因此最好在 Firestore 中执行事务和批量写入之类的操作,但适用于存储 @muco2 这不可避免地会发生。有关更多信息,请查看以下post 的回答。但是,事务并不能解决这个问题,只能在将数据写入 Firestore 时使用。【参考方案3】:

我建议您等待图片上传到 firebase,从 storageRef 获取 URL,然后将 Url 推送到数据库中,如下所示。 我正在使用 javascript 方法,希望您能了解如何实现您的需求。

<input type="file" value="" name="Photo" class="btn btn-info" id="fileButton" accept="image/*"> //html Code

在js文件中,添加事件监听器

var fileButton = document.getElementById('fileButton');
fileButton.addEventListener("change",function(e)
   var file= e.target.files[0];
   //create storage ref to the firebase storage
   var storageRef = firebase.storage().ref('your Path Name').child(file.name);
   var task = storageRef.put(file);
   task.on("state_changed",function(snapshot)
      var percentage= snapshot.bytesTransferred/snapshot.totalBytes) *100;
      if(percentage==100)
          storageRef.getDownloadURL().then(function (url) 
             // You will get the Url here.
            var firebaseRef=firebase.database().ref("Your path Name);
            firebaseRef.push(url).then(function()
              alert("Image Uploaded and also updated to the database");
           );
          );
      
   );
);

我希望这对您有所帮助,这发生在单个事务中。

【讨论】:

这不是单笔交易。如果数据库推送失败,文件仍然上传。【参考方案4】:

这是使用事务以外的另一种方法。您可以使用 Firebase Cloud Functions 存储触发器。您可以编写一个云函数来获取上传图片的下载 URL,然后将其推送到 Firebase 数据库。

Check this video by firebase about Cloud Function Storage Trigger

【讨论】:

这是迄今为止最好的解决方案,我想知道触发器本身是否会因任何原因而失败,但这种可能性远低于例如用户关闭浏览器。 我一直在我的 android 应用中使用云功能。到目前为止,我从来没有遇到过触发器失败的情况。 *** 该视频已于 2018 年 4 月 2 日弃用 *** 请访问 firebase.google.com/docs/functions/gcp-storage-events .. 了解最新信息。

以上是关于如何在单个事务中将图像上传到 Firebase 存储并在数据库中保存参考?的主要内容,如果未能解决你的问题,请参考以下文章

在 React Native 中将图像上传到 Firebase 存储时出现错误 400 Bad Request

如何在 Node.js 中将文件上传到 GCloud?

从 foreach 中删除单个图像(Firebase 存储)

在android中将图像作为BLOB上传到SQL

如何使用 YDN-DB 在单个事务中将数据保存到 websql

成功将图像上传到 Firebase 存储后,Firebase 获取下载 URL