如何使用Firebase Storage存储“直接链接”到图像

34

我需要通过直接链接访问存储在Firebase Storage上的图片, 例如:

http://myfirebasehost.com/storage/imgIwant.png
据我所知,它只能使用协议gs://来处理这种类型的URL,但链接无法访问,只能在SDK api中使用。 我需要使用Firebase平台,按照上述描述找到一种解决方案,如果不可能,请提供其他建议。我的代码有常量链接到图像,更新该图片必须进行新部署。相反,我想要在同一URL中更新图像。根据我所知,使用Storage提供的URL无法通过链接访问,Firebase似乎无法完成此操作。 另一种选择可能是将图像转换为Base64并保存在数据库中,但这将非常耗时且不切实际。

1
你似乎在让你的代码运行时遇到了问题。在Stack Overflow上获取帮助的最佳方式是使用最少量的代码重现问题,并将该代码发布在这里。 - Frank van Puffelen
也许这可以帮助你 - https://dev59.com/wp3ha4cB1Zd3GeqPaNFa#62073071 - Naman Garg
9个回答

25

如何将您的gs存储位置转换为示例中的直接网址

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

第一步确保URL转义您的Blob路径。例如,将正斜杠(/)替换为%2F,将空格()替换为%20。

第二步确保在需要时打开读取访问权限。以下是一个开放规则以便实现:

service firebase.storage {
  match /b/{bucket}/o {
    match /{allPaths=**} {
      allow read: if true;
      allow write: if request.auth != null;
    }
  }
}

我之前认为如果查询字符串中缺少“token”参数,URL将无法正常工作。但是我刚刚尝试了一下,没有出现任何问题。+1 - Yogi
4
可以不带有"?alt=media"这个参数吗? - A Israfil
@Roberto OOC,Firebase存储安全规则还有效吗?或者说任何拥有链接的人都可以访问文件吗?如果有安全措施,那么认证是如何处理的?哈哈 - Maksym Moros
1
规则始终运行-如果您这样想,就没有魔法后门链接。 如果您未提供有效的令牌,则 request.auth 将为空。 在上面的开放规则集中,allow read: if true 表示所有读取都通过,包括无令牌请求。 - fionbio

20

使用 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库进行下载。我们还提供了从引用中下载这些文件的功能,因此您无需获取第三方库,只需使用我们即可。

我强烈建议阅读我们的文档以获取更多信息。


3
这个令牌会改变吗?我想在数据库中保存与对象相关联的完整URL,并稍后使用它(而不是在子级上使用getDownloadUrl)。 - DoruChidean
4
当您覆盖文件或通过网络控制台使令牌无效时,令牌会更改。 - Mike McDonald
1
从后端的角度来看,这个答案并不有用。移动用户没有安全的方式访问Firebase存储(除非他们有账户)。所以我必须创建下载链接,但是在Python Admin API或REST功能中没有这样的方法。因此,Firebase别无选择,只能给予公共访问权限(而我不想这样做),或者使用Google云存储而不是Firebase存储通过后端服务下载图像。因此,对我来说,后端API或管理API是最后关心的,主要针对移动用户,使Firebase逃脱困难。 - makkasi
1
为什么我可以直接从 https://firebasestorage.googleapis.com/v0/bucket/object?alt=media 访问文件,还需要令牌? - hkchakladar
1
@RuslanStelmachenko,如果您的读取规则允许公共读取访问,则不需要令牌。显然,除非对象确实是公共的,否则我们不建议公共读取访问。全局使用read:false并仅在需要使用应用程序时生成可共享的URL很容易,但我们建议使用安全规则以更多地控制访问权限。 - Mike McDonald
显示剩余11条评论

9

2020年,我为了解决Swift中的CharacterSet对于编码字符串(或者可能是我遗漏了什么)的限制而费尽了一番周折。

以下是我成功将Firebase Storage上Blob的“路径”(文件夹路径)转换为完整直接URL的步骤:

  1. 获取上传后存储的元数据(在iOS中,我们有一个名为FIRStorageMetadata的类),从中获取名为pathbucket的字符串对象。
  2. 恰当地编码路径字符串!这很重要!如果您错过了某个字符,您将无法下载完整的直接URL时会收到错误信息。

    • 在iOS中,我使用字符集urlHostAllowed编码路径字符串。但是,正如我在上面所说的那样,这还不够,因为没有一个字符集能将字符串编码为包括“+”加号的URL。
    • 因此,在使用urlHostAllowed进行编码后,我调用了替换字符串方法,将“+”替换为“%2B”
    • 用一种测试编码结果是否正确的方法是将您的编码结果与您可以从Firebase Storage UI获得的结果进行比较。
  3. 连接字符串:

完成!

常见问题解答

  1. 我们可以省略token吗?是的,当然可以。它可以正常工作。自从我学习它以来一直这样做。
  2. 我们可以省略?alt=media吗?不行!您只会得到一个json格式的字符串而不是文件。

8

想要获取链接的人可以:

控制台 > 存储

选择具体的照片,你将会看到下方的链接。 图片描述


1
这似乎不再适用了? - Crashalot
它的工作原理如下:https://github.com/firebase/firebase-admin-node/issues/694 - Antoine

3
将文件转换为公共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 如果没有文件夹(public),则链接如下: https://firebasestorage.googleapis.com/v0/b/funzone-website.appspot.com/o/logo.jpg?alt=media

1
它是有效的,但我们必须将规则设置为特定文件夹为真,即没有认证,否则会抛出错误。 - Rajesh

2

2020

Firebase连接到Google Cloud平台:

您需要在Google Cloud平台上将存储桶或所需对象设为公共,然后您将获得一个简单的链接,无需编辑:

使数据公开

您也可以使用链接而不必使数据公开(但是那样您必须登录才能访问):

转到Google Cloud平台 > 选择您的项目 > 存储 > 浏览器 > 打开bucket appID.appspot.com > 打开任何对象,然后您就有了Firebase控制台提供的uri和URL。

  • 我尝试了这里提供的所有方法,但它们不再起作用

0
service firebase.storage {
  match /b/{bucket}/o {
    match /{allPaths=**} {
      allow  write: if request.auth != null;
      allow  read: if request.auth == null;
    }
  }
}

您可以尝试这个,因为它允许公开读取访问。

0

另一个选项是格式为URL的:

https://storage.googleapis.com/PROJECT-ID/FILEPATH

PROJECT-ID: Firebase 项目的项目 ID

FILEPATH: 项目文件的路径


0
如果您希望您的图像是公开的 -
请将以下内容添加到您的存储规则中。
service firebase.storage {
  match /b/{bucket}/o {
    match /{allPaths=**} {
      allow  write: if request.auth != null;
      allow  read: if request.auth == null;
    }
  }
}

然后你可以像这样使用它

export const getMedia = (folderId, mediaId) =>`https://firebasestorage.googleapis.com/v0/b/${process.env.NEXT_PUBLIC_FIREBASE_STORAGE_BUCKET}/o/${folderId}%2F${mediaId}?alt=media`;

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接