typescript - firebase fonksiyonu ile resmi firebase bulut depolamaya başarılı bir şekilde kaydettikten sonra indirme URL'sini al


Firebase fonksiyonunda bir resmi cloud storage'a kaydettikten sonra indirme URL'si almada sorun yaşıyorum. Aşağıda, base64 stringi JPEG olarak Firebase cloud storage'a kaydetmek için yazdığım Typescript Firebase HTTP fonksiyonum bulunuyor. Sonucu logladığımda her zaman boş geliyor. İndirme URL'sini almak için bu linki takip ettim: "firebase-admin ile yüklenen dosyadan Genel URL Alma". Ama bana şu hatayı veriyor: "SigningError: Identity and Access Management (IAM) API has not been used in project 81673989436 before or it is disabled." Ve takip edebileceğim basit bir örnek bulamadım. Planım, cloud storage'a yüklendikten sonra Firestore tablomı güncellemek.

export const publishImage = functions.https.onRequest((req, res) => {
// Convert the base64 string back to an image to upload into the Google 
// Cloud Storage bucket
const base64EncodedImageString=req.body.image.replace(/^data:image\/jpeg;base64,/, "");
const mimeType = 'image/jpeg';
const randomFileName = crypto.randomBytes(16).toString('hex') + '.jpeg';    
const imageBuffer = new Buffer(base64EncodedImageString, 'base64');

const bucket = admin.storage().bucket();

// Upload the image to the bucket
const file = bucket.file('images/' + randomFileName);
file.save(imageBuffer, {
    metadata: { contentType: mimeType },
}).then(result => {
    console.log(result);
    file.makePublic();
    file.getSignedUrl({
        action: 'read',
        expires: '03-09-2491'
    }).then(urls => {
        console.log(urls[0]);
    })
});
return res.status(200).send("NOT WORKING");    
})

Hata Firebase konsolunda aşağıdaki gibidir. Hata olmasına rağmen, resmi depolama alanına kaydedebiliyorum.

SigningError: Bu işlemi service account üzerinde gerçekleştirmek için iam.serviceAccounts.signBlob izni gereklidir: projects/vmsystem-4aa54/serviceAccounts/[email . at /user_code/node_modules/@google-cloud/storage/src/file.js:1715:16 at Request._callback (/user_code/node_modules/@google-cloud/storage/node_modules/google-auto-auth/index.js:356:9) at Request.self.callback (/user_code/node_modules/@google-cloud/storage/node_modules/request/request.js:186:22) at emitTwo (events.js:106:13) at Request.emit (events.js:191:7) at Request. (/user_code/node_modules/@google-cloud/storage/node_modules/request/request.js:1163:10) at emitOne (events.js:96:13) at Request.emit (events.js:188:7) at IncomingMessage. (/user_code/node_modules/@google-cloud/storage/node_modules/request/request.js:1085:12) at IncomingMessage.g (events.js:292:16)

İndirme URL'sini nasıl alabilirim?

Kafam karışıyor. Şimdi değişikliklerden sonra fonksiyonu güncelleme kısmında takıldım. Aşağıda admin için başlatmam var.

 import * as admin from 'firebase-admin';
 const serviceAccount = require('./../service_account.json');

 try {   
 // admin.initializeApp(functions.config().firebase); // initial
 admin.initializeApp({
     credential: admin.credential.cert(serviceAccount),
     databaseURL: "https://vmsystem-4aa54.firebaseio.com"
 });
 } catch(e) {}
 import * as simpletest from './simpletest';
 export const testsomething = simpletest.helloWorld;

Cevap #1

Burada tüm kodu göstermiyorsunuz (örneğin, admin oluşturmak için Firebase Admin SDK'sını nasıl başlattığınızı). Bu yüzden bunu başlatmak için proje varsayılan kimlik bilgilerini şu şekilde kullandığınızı varsayacağım:

import * as admin from 'firebase-admin'
admin.initializeApp()

Bu, yönetici SDK'sına girip Cloud Storage API'lerini kullanırken getSignedUrl'ü kullanabilmek için yeterli değildir. Eğer getSignedUrl kullanmak istiyorsanız, konsolda oluşturduğunuz özel bir servis hesabının kimlik bilgilerini sağlamanız gerekecektir.

Bu kimlik bilgilerini functions klasörünüzde yourServiceAccount.json adlı bir dosyaya koyduğunuzu varsayarsak, yönetici SDK'sını bu kimlik bilgileri ile şöyle başlatmalısınız:

import * as serviceAccount from 'yourServiceAccount.json';
const adminConfig = JSON.parse(process.env.FIREBASE_CONFIG)
adminConfig.credential = admin.credential.cert(<any>serviceAccount)
admin.initializeApp(adminConfig);

Bunun, sadece varsayılan proje yapılandırmasını FIREBASE_CONFIG'tan alıp hizmet hesabını bunlara eklemek olduğunu unutmayın.

Bir JSON dosyasını içe aktarmak için, ayrıca bir dosyaya (typings.d.ts olarak adlandırılan) sahip olmanız gerekecek:

declare module "*.json" {
  const value: any;
  export default value;
}

Cevap #2

Teşekkürler @Doug Stevenson. Sanırım bir cevap buldum.

  1. Dağıtım hatalarını yeni bir proje oluşturarak çözerim.

  2. Unhandled rejection sorununu çözmek için başlatmamı aşağıdaki koda değiştiriyorum. Firebase projenizde Proje Ayarları altında Hizmet Hesaplarına gidin ve Firebase Admin SDK altında yeni özel anahtar oluşturun.

    const serviceAccount = require('./path/to/serviceaccount.json');
    admin.initializeApp({
      credential: admin.credential.cert(serviceAccount),
      databaseURL: '<ur database url>', // check it under service accounts
      storageBucket: '<ur storage bucket url>' //check it in script snippet require to add to your website.
    });
    

İlgili makaleler