从使用Cloud Functions for Fire上传的文件获取下载url

在Firebase存储中使用Firebasefunction上传文件后,我想获取文件的下载url。

我有这个 :

... return bucket .upload(fromFilePath, {destination: toFilePath}) .then((err, file) => { // Get the download url of file }); 

目标文件有很多参数。 即使一个名为mediaLink 。 但是,如果我尝试访问这个链接,我得到这个错误:

 Anonymous users does not have storage.objects.get access to object ... 

有人可以告诉我如何获得公共下载url?

谢谢

您需要通过@ google-cloud / storage NPM模块使用getSignedURL生成签名的URL。

例:

 const gcs = require('@google-cloud/storage')({keyFilename: 'service-account.json'}); // ... const bucket = gcs.bucket(bucket); const file = bucket.file(fileName); return file.getSignedUrl({ action: 'read', expires: '03-09-2491' }).then(signedUrls => { // signedUrls[0] contains the file's public URL }); 

您需要使用您的服务帐户凭据初始化@google-cloud/storage ,因为应用程序默认凭据将不够用。

以下是如何在上传时指定下载令牌的示例:

 const UUID = require("uuid-v4"); const fbId = "<YOUR APP ID>"; const fbKeyFile = "./YOUR_AUTH_FIlE.json"; const gcs = require('@google-cloud/storage')({keyFilename: fbKeyFile}); const bucket = gcs.bucket(`${fbId}.appspot.com`); var upload = (localFile, remoteFile) => { let uuid = UUID(); return bucket.upload(localFile, { destination: remoteFile, uploadType: "media", metadata: { contentType: 'image/png', metadata: { firebaseStorageDownloadTokens: uuid } } }) .then((data) => { let file = data[0]; return Promise.resolve("https://firebasestorage.googleapis.com/v0/b/" + bucket.name + "/o/" + encodeURIComponent(file.name) + "?alt=media&token=" + uuid); }); } 

然后打电话

 upload(localPath, remotePath).then( downloadURL => { console.log(downloadURL); }); 

这里的关键是在metadata metadata选项属性中嵌套了一个metadata对象。 将firebaseStorageDownloadTokens设置为uuid-v4值会告诉Cloud Storage将其用作其公共身份validation令牌。

非常感谢@martemorfosis

成功使用的一种方法是在文件的元数据完成上传后,将UUID v4值设置为名为firebaseStorageDownloadTokens的键,然后在Firebase用于生成这些url的结构中自行组装下载url,例如:

 https://firebasestorage.googleapis.com/v0/b/[BUCKET_NAME]/o/[FILE_PATH]?alt=media&token=[THE_TOKEN_YOU_CREATED] 

我不知道使用这种方法有多“安全”(因为Firebase可能会改变它将来如何生成下载URL),但是它很容易实现。

对不起,但我不能发表评论上面的问题,因为缺less名誉,所以我会包括在这个答案。

如上所述,通过生成一个签名的Url,而不是使用service-account.json,我认为你必须使用serviceAccountKey.json,你可以在这里生成(相应地replaceYOURPROJECTID)

https://console.firebase.google.com/project/YOURPROJECTID/settings/serviceaccounts/adminsdk

例:

 const gcs = require('@google-cloud/storage')({keyFilename: 'serviceAccountKey.json'}); // ... const bucket = gcs.bucket(bucket); // ... return bucket.upload(tempLocalFile, { destination: filePath, metadata: { contentType: 'image/jpeg' } }) .then((data) => { let file = data[0] file.getSignedUrl({ action: 'read', expires: '03-17-2025' }, function(err, url) { if (err) { console.error(err); return; } // handle url }) 

对于那些想知道Firebase Admin SDK serviceAccountKey.json文件应该去的地方。 只需将其放置在函数文件夹中并照常部署。

它仍然让我感到困惑,为什么我们不能像Javascript SDK那样从元数据中获得下载地址。 生成一个最终会过期并将其保存在数据库中的url是不可取的。