从使用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是不可取的。