6

Próbuję utworzyć skrypt w Cloud Functions for Firebase, który zareaguje na zdarzenie db i usunie obraz, który ma swoją ścieżkę w jednym z parametry ("fullPath").problemy podczas usuwania obrazu za pomocą funkcji chmurowych dla Firebase i @ google-cloud/storage

jest to kod używam:

'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); 
     }); 

    }); 

błąd Dostaję:

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' } 

Próbowałem zi bez poświadczeń do Google chmura/przechowywanie (myśląc, że może zostać automatycznie wypełniony, gdy jestem w firebase.functions - czy ich potrzebuję?). Próbowałem dodać slash do ścieżki pliku. Sprawdziłem, że plik faktycznie istnieje w wiadrze (nawet tho file.exists() zwraca false). podane przeze mnie poświadczenia są dla iam i utworzone z uprawnieniami administratora dla usługi przechowywania.

Mam również włączyć konto rozliczeniowe na bezpłatnym abonamencie.

jakieś pomysły?

Odpowiedz

5

ok, więc mam to rozwiązane. oto moje wnioski:

  • musisz dodać do swoich nazw pojemników ".appspot.com". Nie jest on nigdzie zapisany w dokumentach, a uzyskanie nazwy zasobnika w bazie danych jest wystarczająco trudne dla kogoś, kto nie jest zaznajomiony z chmurą Google. Mam nadzieję, że dodadzą ten mały spokój informacji do swoich dokumentów lub wyjaśnią, jakie jest imię waszego wiadra w bazie ogniowej.
  • użyj zmiennej środowiskowej process.env.GCLOUD_PROJECT, powinien mieć identyfikator projektu identyczny z identyfikatorem zasobnika w firebase. ponownie, pamiętaj, aby dodać do niej przyrostek .appspot.com.
  • w odniesieniu do referencji do GCS, nie musisz podawać ich podczas korzystania z funkcji chmury dla bazy Firebase. wydajesz się być już uwierzytelniony.
3

Upewnij nazwę wiadro nie obejmują gs://

Np. zamiast gs://my-project-id.appspot.com używać my-project-id.appspot.com

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

Może to ci się stało (jak to miało miejsce do mnie) jeśli skopiować nazwy wiadro z, na przykład, kod Androida, gdzie można wykorzystać pełny adres URL, aby połączyć ze składowaniem, tj. storage.getReferenceFromUrl('gs://my-proj...

.

Wygląda na to, że zmienna projectId używana do inicjowania gcs nie wymaga przyrostka appspot.com (ale nie powinna się zepsuć, jeśli jest dostępna). To znaczy. projectId:'my-project-id' powinno wystarczyć.

Na koniec GCS node package docs stwierdza, że ​​należy wygenerować oddzielny JSON, aby przekazać jako keyFilename, aby przetestować lokalnie. Dobra wiadomość to - możesz użyć klucza SDK Firebase Admin, jak to opisano w Get Started Server/Admin docs.