使用适用于Firebase的Cloud Functions和@ google-cloud / storage删除图片时出现问题

我正在尝试在Fire的Cloud Functions中创build一个脚本,该脚本将对db事件作出反应,并删除其中一个参数(“fullPath”)中具有其path的图像。

这是我使用的代码:

'use strict'; const functions = require('firebase-functions'); const request = require('request-promise'); const admin = require('firebase-admin'); const gcs = require('@google-cloud/storage')({ projectId: 'XXXXXXX', credentials: { // removed actual credentials from here }}); admin.initializeApp(functions.config().firebase); // Deletes the user data in the Realtime Datastore when the accounts are deleted. exports.removeImageOnNodeRemoval = functions.database .ref("images/{imageId}") .onWrite(function (event) { // exit if we are creating a new record (when no previous data exists) if (!event.data.previous.exists()) { console.log("a new image added"); return; } // exit if we are just trying to update the image if (event.data.exists()) { console.log("image is been modified"); return; } let previousData = event.data.previous.val(); if(!previousData || !previousData.fullPath){ console.log("no data in the previous"); return; } let bucketName = 'XXXXXXX'; console.log("default bucketName", gcs.bucket(bucketName)); let file = gcs.bucket(bucketName).file(previousData.fullPath); console.log('the file /'+previousData.fullPath, file); file.exists().then(function(data) { let exists = data[0]; console.info("file exists", exists); }); file.delete().then(function() { // File deleted successfully console.log("image removed from project", previousData.fullPath); }).catch(function(error) { // Uh-oh, an error occurred! console.error("failed removing image from project", error, previousData); }); }); 

我得到的错误:

 failed removing image from project { ApiError: Not Found at Object.parseHttpRespBody (/user_code/node_modules/@google-cloud/storage/node_modules/@google-cloud/common/src/util.js:192:30) at Object.handleResp (/user_code/node_modules/@google-cloud/storage/node_modules/@google-cloud/common/src/util.js:132:18) at /user_code/node_modules/@google-cloud/storage/node_modules/@google-cloud/common/src/util.js:465:12 at Request.onResponse [as _callback] (/user_code/node_modules/@google-cloud/storage/node_modules/retry-request/index.js:120:7) at Request.self.callback (/user_code/node_modules/@google-cloud/storage/node_modules/request/request.js:188:22) at emitTwo (events.js:106:13) at Request.emit (events.js:191:7) at Request.<anonymous> (/user_code/node_modules/@google-cloud/storage/node_modules/request/request.js:1171:10) at emitOne (events.js:96:13) at Request.emit (events.js:188:7) at IncomingMessage.<anonymous> (/user_code/node_modules/@google-cloud/storage/node_modules/request/request.js:1091:12) at IncomingMessage.g (events.js:291:16) at emitNone (events.js:91:20) at IncomingMessage.emit (events.js:185:7) at endReadableNT (_stream_readable.js:974:12) at _combinedTickCallback (internal/process/next_tick.js:74:11) at process._tickDomainCallback (internal/process/next_tick.js:122:9) code: 404, errors: [ { domain: 'global', reason: 'notFound', message: 'Not Found' } ], response: undefined, message: 'Not Found' } { contentType: 'image/png', fullPath: 'images/1491162408464hznsjdt6oaqtqmukrzfr.png', name: '1491162408464hznsjdt6oaqtqmukrzfr.png', size: '44.0 KB', timeCreated: '2017-04-02T19:46:48.855Z', updated: '2017-04-02T19:46:48.855Z' } 

我已经尝试过和没有凭据谷歌云/存储(认为他们可能会得到自动填充,而我在firebase.functions – 我需要他们吗?)。 我已经尝试添加一个斜杠文件的path。 我已经validation文件实际上存在于存储桶中(甚至tho file.exists()返回false)。 我提供的凭据是我为存储服务的pipe理员权限创build的iam。

我还启用了免费计划中的结算帐户。

有任何想法吗?

好的,所以我解决了这个问题。 这里是我的结论:

  • 您需要将“.appspot.com”添加到您的存储桶名称中。 它没有写在文档中的任何地方,并获得您的存储桶名称在firebase是很难的人不熟悉的谷歌云。 我希望他们能够把这个小小的信息和平添加到他们的文档中,或者说清楚你在firebase中的名字是什么。
  • 使用环境variablesprocess.env.GCLOUD_PROJECT ,它应该有你的项目ID是相同的在你的桶ID在firebase。 再次,请记住将.appspot.com后缀添加到它。
  • 关于GCS的凭证,当您使用云端function作为Firebase时,您不需要提供凭证。 你似乎已经被authentication了。

确保您的存储桶名称包含gs://

例如。 而不是gs://my-project-id.appspot.com使用my-project-id.appspot.com

let bucket = gcs.bucket('my-project-id.appspot.com')

这可能发生在你身上( 就像我这样做 ),如果你从你的存储桶中复制你的存储桶的名字,例如你可以使用完整的URL来连接存储。 storage.getReferenceFromUrl('gs://my-proj...

此外,似乎你用来初始化gcsprojectIdvariables不需要appspot.com后缀(但是如果你有它,它不应该中断)。 IE浏览器。 projectId:'my-project-id'应该就足够了。

最后, GCS节点包文档声明您需要生成单独的JSON以传递keyFilename在本地进行testing。 好消息是,您可以使用Firebase Admin SDK密钥,如“入门服务器/pipe理员”文档中所述 。