如何使用 Firebase 存储“直接链接”到图像
Posted
技术标签:
【中文标题】如何使用 Firebase 存储“直接链接”到图像【英文标题】:How to Store "direct link" to an image using Firebase Storage 【发布时间】:2016-12-11 07:22:24 【问题描述】:我需要通过直接链接访问存储在 Firebase 存储中的图像,例如
http://myfirebasehost.com/storage/imgIwant.png
据我所知,它只能使用gs://
协议的这种类型的URL,但是,它不能通过链接访问,只能在SDK api中访问。
我需要一个使用 Firebase 平台的解决方案,如果不可能,请接受其他建议。
我的代码具有指向图像的链接的常量。事实证明,如果我想更新这张图片,我必须进行新的部署。相反,我想在同一个 URL 更新图像。使用 firebase 是不可能的(据我所知),因为 Storage 提供的 URL 无法通过链接访问。
另一种选择可能是将图像转换为 base64 并存储在数据库中,但这会非常广泛且不切实际。
【问题讨论】:
您的代码运行似乎有问题。在 Stack Overflow 上获得帮助的最佳方式是 reproduce the problem in a minimal amount of code 并在此处发布该代码。 也许这可以帮助你 - ***.com/questions/41423890/… 【参考方案1】:例如如何将您的gs storage location
翻译成direct url
:
gs://nobs-f32f2.appspot.com/profile/1s_by_wlop-dc1sdan.jpg
变成
https://firebasestorage.googleapis.com/v0/b/nobs-f32f2.appspot.com/o/profile%2F1s_by_wlop-dc1sdan.jpg?alt=media
1st
一定要对你的 blob 路径进行 URL 转义。例如,将正斜杠 (/
) 交换为 %2F,将空格 () 交换为 %20。
2nd
确保您已在需要时打开读取访问权限。这是一个开放的移动规则:
service firebase.storage
match /b/bucket/o
match /allPaths=**
allow read: if true;
allow write: if request.auth != null;
【讨论】:
我认为在查询字符串中缺少“token”参数时,该 URL 不会起作用。然而,我只是试了一下,没有问题。 +1 是否可以没有 ?alt=media ? @Roberto OOC,firebase 存储安全规则仍然有效吗?或者知道链接的任何人都可以访问该文件吗?如果安全是的,那么身份验证是如何处理的?大声笑 规则始终运行 - 如果您认为没有神奇的后门链接。如果您不提供有效的令牌,request.auth
将为空。在上面的开放规则集中,allow read: if true
表示所有内容都通过读取,包括无令牌请求。【参考方案2】:
使用 Firebase 存储,您可以使用两个 URL 来表示文件:
// "Private" internal URL, only accessible through Firebase Storage API
// This is protected by Firebase Storage Security Rules & Firebase Auth
gs://bucket/object
// "Public" unguessable URL, accessible by anyone with the link
// This is secured because that token is *very* hard for someone to guess
https://firebasestorage.googleapis.com/v0/bucket/object?alt=media&token=<token>
第一个选项要求您使用reference.getDownloadURL()
方法将内部gs://
URL 转换为公共https://
URL。
第二个选项允许您与受信任的个人共享此公开但无法猜测的 URL,并允许他们访问内容而无需通过 Firebase 身份验证或使用您的应用程序 - 想想与 Google 相册共享家庭照片。除非您希望使用干净的 URL 进行公开共享,否则这种行为可能已经足够好了。您可以在浏览器中使用此 URL,或使用任何其他 HTTP 库来下载它。我们还提供下载这些文件的功能(参考),因此您无需获取第三方库,只需使用我们即可。
我强烈建议阅读our docs 了解更多信息。
【讨论】:
令牌是否会改变?我想将完整的 URL 保存在与对象关联的数据库中,以便以后使用。 (不对孩子使用 getDownloadUrl) @DoruChidean 当您覆盖文件或在 Web 控制台中使令牌无效时,令牌会更改。 从后端的角度来看,这个答案没有用。移动用户没有安全的方式来访问 firebase 商店(除非他们有帐户)。所以我必须创建它们下载 url,但在 python Admin API 或这样的 REST 功能中没有这样的方法。因此,firebase 让我别无选择,只能提供公共访问权限(我不想这样做),或者提供使用 Google 云存储而不是 Firebase 存储通过后端下载图像的服务。所以在我看来,后端 API 或管理 API 是最后一个问题,主要针对移动用户,使 Firebase 难以逃脱。 当我可以直接从https://firebasestorage.googleapis.com/v0/bucket/object?alt=media
访问文件时为什么需要令牌?
@RuslanStelmachenko 正确,如果您的读取规则允许公共读取访问,则您不需要令牌。显然,我们不建议对对象进行公共读取访问,除非它们确实是公共的。它很容易在全局范围内使用 read:false 并且仅在您希望以这种方式使用应用程序时生成可共享的 URL,但我们建议使用安全规则来更好地控制访问。【参考方案3】:
对于那些只想获得链接的人
在console > Storage
选择一张特定的照片,您将看到下面的链接。
【讨论】:
这似乎不再适用? 它的工作原理是这样的:github.com/firebase/firebase-admin-node/issues/694【参考方案4】:2020 年,我很难弄清楚这一点,尤其是因为 Swift 中 CharacterSet
对字符串编码的限制(或者很可能我遗漏了一些东西)。
以下是我如何在 Firebase 存储上转换 Blob 的“路径”(文件夹路径)的步骤(上传后)。
-
给定上传后的存储元数据,(在 ios 中,我们有名为
FIRStorageMetadata
的类。)获取名为 path
和 bucket
的字符串对象。
正确编码路径字符串!这个很重要!如果您错过了某个字符,那么当您尝试下载完整的直接 URL 时显然会出错。
在 iOS 中,我使用 CharacterSeturlHostAllowed
对路径字符串进行编码。但是,这还不够,就像我在上面所说的那样,要么没有 CharacterSet 将字符串编码为包含 "+' 加号的 URL。
所以使用urlHostAllowed
编码后,我调用replace出现字符串方法,将"+"替换为"%2B"
测试您是否正确编码路径字符串的一种方法是将您的编码结果与您可以从 Firebase 存储 UI 获得的结果进行比较。
连接字符串:
“https://firebasestorage.googleapis.com/v0/b/” 桶对象 "/o/" 正确编码的路径对象。 "?alt=media"瞧!
常见问题解答
-
我们可以省略 token 吗?是的,当然了。它只是工作。自从学会了就一直在做。
我们可以省略
?alt=media
吗?没有!你只会得到一个 json 格式的字符串,而不是文件。
【讨论】:
【参考方案5】:2020
Firebase 已连接到 Google Cloud Platform:
您需要在 Google Cloud Platform 上公开存储桶或所需对象,然后您将获得一个简单的链接,无需对其进行任何编辑:
Making data public
您也可以在不公开数据的情况下使用该链接(但您必须先登录才能访问):
转到Google Cloud Platform > 选择您的项目 > 存储 > 浏览器 > 打开存储桶 appID.appspot.com > 打开任何对象,然后您就有了 uri(Firebase 控制台提供的)和 URL。
我在这里尝试了所有给定的方法,但它们不再起作用了【讨论】:
【参考方案6】:转换为公共 URL 检查示例。
假设链接是 gs://funzone-website.appspot.com/public/logo.jpg
让 g=funzone-website.appspot.com/public/logo.jpg
如果有文件夹,则用 % 替换文件路径。在上面的例子中,public是一个文件夹,添加?alt=media并添加o。
现在 g=funzone-website.appspot.com/o/public%2Flogo.jpg?alt=media
用 %2F 转换和替换路径(/)
要转换这个使用https://firebasestorage.googleapis.com/v0/b/g
或
https://firebasestorage.googleapis.com/v0/b/funzone-website.appspot.com/o/public%2Flogo.jpg?alt=media
如果没有文件夹(公共)则链接是
https://firebasestorage.googleapis.com/v0/b/funzone-website.appspot.com/o/logo.jpg?alt=media
【讨论】:
它成功了,但是我们必须将特定文件夹的规则设置为true,即不进行身份验证,否则会引发错误【参考方案7】:另一个选项是以下格式的 URL:
https://storage.googleapis.com/PROJECT-ID/FILEPATH
PROJECT-ID
:Firebase 项目的项目 ID
FILEPATH
: 项目文件路径
【讨论】:
【参考方案8】:service firebase.storage
match /b/bucket/o
match /allPaths=**
allow write: if request.auth != null;
allow read: if request.auth == null;
你可以试试这个,因为它允许公共读取访问
【讨论】:
以上是关于如何使用 Firebase 存储“直接链接”到图像的主要内容,如果未能解决你的问题,请参考以下文章
如何将聊天中的加载图像替换为使用 ReactJS 上传到 Firebase 存储的图像?