6

我想創建一個腳本在雲功能的Firebase,將對db事件作出反應,並刪除一個圖像,其路徑之一params(「fullPath」)。使用雲功能刪除圖像的Firebase和@谷歌雲/存儲

這是我使用的代碼:

'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中的im時自動填充 - 我需要它們嗎?)。我曾嘗試向該文件的路徑添加斜槓。我已驗證該文件實際上存在於存儲桶中(甚至tho file.exists()返回false)。我提供的憑證是爲iam創建的,具有存儲服務的管理權限。

我還啓用了免費計劃上的結算帳戶。

有什麼想法?

回答

5

好的,所以我解決了這個問題。這裏是我的結論:

  • 你需要添加到你的水桶名稱的「.appspot.com」。它沒有寫在文檔中的任何地方,並且在Firebase中獲取您的存儲桶名稱對於不熟悉谷歌雲的人來說已經夠難了。我希望他們能夠在文檔中增加這些小小的信息和平,或者明確你的存儲桶在firebase中的名字。
  • 使用環境變量process.env.GCLOUD_PROJECT,它應該使您的項目ID與您在Firebase中的存儲桶ID相同。再次,請記住將.appspot.com後綴添加到它。
  • 有關GCS的憑證,您不需要在爲Firebase使用雲功能時提供憑證。你似乎已經被認證了。
3

確保你的水桶名包括gs://

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

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

這可能發生在你身上(因爲它沒有給我)如果從,複製你的水桶的名字,例如,Android的代碼,在那裏你可以使用完整的URL連接與存儲,即。 storage.getReferenceFromUrl('gs://my-proj...

另外,它看起來projectId變量你用來初始化gcs不需要appspot.com後綴(但它不應該打破,如果你有它包括在內)。 IE瀏覽器。 projectId:'my-project-id'應該就夠了。

最後,GCS node package docs表示您需要生成單獨的JSON,以便通過keyFilename來本地測試。好消息是,您可以使用Firebase Admin SDK密鑰,如Get Started Server/Admin docs中所述。