如何在单个事务中将图像上传到 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
从 foreach 中删除单个图像(Firebase 存储)