Firebase 存储 URL 随新令牌不断变化

Posted

技术标签:

【中文标题】Firebase 存储 URL 随新令牌不断变化【英文标题】:Firebase storage URL keeps changing with new token 【发布时间】:2018-02-16 02:14:15 【问题描述】:

我正在尝试使用 firebase 数据库和存储构建社交媒体应用程序。以下是预期的流程。

    用户上传个人资料图片,该图片存储在当前用户文件夹的 firebase 存储中,并且 URL 存储在 firebase 数据库中以便快速访问。 (工作正常)

    用户发表他们的想法。这会在数据库中保存用户信息,例如发布消息、用户名和个人资料图像 URL。 (工作正常)。

问题

现在的问题是,假设用户更新了他或她的个人资料图片,这会覆盖 firebase 存储中旧的个人资料图片(以便管理存储并使用户图片在所有 cmets 和帖子中都相同)。在发布消息活动中,由于令牌已更改,因此无法访问旧的个人资料图片 URL。

问题

我想知道如何解决这个问题,以使 Firebase 存储 URL 在所有更新中都是静态的(即相同的)。

注意

使用 Picasso 而不是 firebase 方法来获取图像

【问题讨论】:

您找到解决方案了吗? atm处理同样的问题 @Harry 是的,我所做的是在所有用户的数据库中为个人资料图像使用标准名称,并且在存储上使用此名称。例如,我使用标准的“avatar.jpg”作为头像名称,在存储中我为每个用户使用了唯一的路径(users/userId/profile/avatar.png)。有了这个,每当用户更新他/她的个人资料图片时,它将用一个具有相同名称的新文件 avata.png 覆盖旧的 avatar.png。希望对您有所帮助,如果您需要更多说明,请告诉我 我能知道你在数据库中做的URL字符串作为例子吗? @Prodigy 我完全按照您所说的那样处理了 Firebase 存储中图像的路径,但链接中的令牌仍在不断变化。请您提供更多关于您如何解决问题的说明? 抱歉回复晚了。您不必再使用完整的 URL(因为它包含动态令牌),您可以使用 Firebase Glide (firebaseui) 获取图像来执行此操作。如果您需要任何说明或示例代码,我可以为您提供帮助。 【参考方案1】:

由于 URL 图像存储在数据库中,您可以在用户更新他的图片后使用云函数来更新值。

您可以触发 Cloud 函数以响应 Cloud Storage 中文件的更新,请参阅:

https://firebase.google.com/docs/functions/gcp-storage-events

您可以在以下位置找到 Cloud Functions 示例:https://github.com/firebase/functions-samples

完整文档位于:https://firebase.google.com/docs/functions/

【讨论】:

是的,我知道,但是使用 URL 会更加无缝和整洁。 我并不是说您应该放弃使用 URL,而是您可以使用更新时触发的后端进程(云功能)来更新保存在数据库中的 URL /更改文件。 在数据库中随处更新用户的照片 URL 听起来不太可扩展,因为它是一种社交媒体。 Renaud Tarnec 的回答确实解决了问题,但 Prodigy 和 gowithefloww 是对的!如果用户创建了 100 万个帖子,云功能应该将它们全部更改!如果某个用户每天更改一次他的个人资料照片怎么办! Firebase 开发人员真的应该考虑制作静态网址。 @OussamaMahmoudi 是的,我希望他们应该提供静态网址...但是请查看我上面的评论,我提供了一个解决方法,您不必使用函数花费额外的成本【参考方案2】:

虽然这个问题已经问了很久了,但是我注意到有些人仍然觉得解决这个问题很困难,所以我将在下面提供我的解决方案。

第 1 步 由于存储 URL 在更改时始终是动态的(即 posses 令牌),所以我所做的是为所有用户使用存储的图像文件的通用名称,例如 avatar

第 2 步 为每个用户在存储中创建一个目录,如下所示:users/uid/avatar.jpg

第 3 步 使用步骤 2 中的路径拉取或显示图像(见下文)

安卓

StorageReference storageReference = FirebaseStorage.getInstance().getReference("users").child(userId).child("avatar.jpg");
    
Glide.with(context).using(new FirebaseImageLoader()).load(storageReference).diskCacheStrategy(DiskCacheStrategy.ALL)
                .error(R.drawable.ch_white_icon).placeholder(R.drawable.ch_white_icon).into(imageView);

网络

var storage = firebase.storage();
    var pathReference = storage.ref('users/' + userId + '/avatar.jpg');
    pathReference.getDownloadURL().then(function (url) 
        $("#large-avatar").attr('src', url);
    ).catch(function (error) 
        // Handle any errors
    );

有了这个,您就不必再担心动态链接了,每当您将新图片上传到上述路径时,它都会覆盖之前的图片,并且第 3 步中的代码将为您提供新图片。

PS: 对于 android,如果您不想滑行缓存图像,请不要忘记将 DiskCacheStrategy.ALL 更改为 DiskCacheStrategy.NONE,或者如果允许缓存,您可以使用时间戳获取新图像.

【讨论】:

感谢@Prodigy。我会看看我是否可以使用 javascript 框架解决方案来完成这项工作。 @MadMac 我添加了网络实现...希望有帮助 太棒了,效果很好。只需为我节省数百万次写入。感谢@Prodigy。 当 avatar.jpg 使用新文件更新时,这似乎不起作用。显示没有令牌的文件会显示原始文件而不是更新版本,如果您需要更新的文件,似乎仍然需要令牌。 @user1012500 您不需要令牌来显示更新的图像。看来您的图像已被缓存。我在上面解释了如何为 android 禁用它。

以上是关于Firebase 存储 URL 随新令牌不断变化的主要内容,如果未能解决你的问题,请参考以下文章

Firebase 存储安全规则和上传文件的下载令牌

如何使用swift更新firebase中的令牌?

Firebase 存储工件巨大且不断增加

读取 Firebase 存储映像安全规则

从 Flutter Web 应用程序发送 Firebase 存储授权作为 url 参数

来自firebase存储URL的toDataURL显示空白图像[重复]