簡體   English   中英

Google Cloud Function-為什么存儲桶總是返回空文件數組?

[英]Google Cloud Function - Why bucket always returns empty array of files?

我正在嘗試訪問Firebase存儲上存儲的文件,以將它們的列表返回到我的APK。 我做了一個雲功能,即使一切似乎都正確,它也無法正常工作。

index.js

const {Storage} = require('@google-cloud/storage');

const functions = require('firebase-functions');

const images = require('./images.js');

const storage = new Storage({
    projectId: '<my_id>',
    keyFilename: './key.json',
});

const bucket = storage.bucket('<my_bucket>')

exports.getImages = functions.https.onRequest((request, response) => {
    images.getImages(bucket).then(urls => response.send(urls))
})

images.js

module.exports = {
    getImages
}

const query = {
    directory: '/images'
};

async function getImages(bucket) {
    return bucket.getFiles(query).then(files => {
        console.log(files)
        getUrls(files).then(urls => console.log(urls))
            .catch(() => console.error('URLs failure'));
    }).catch(() => console.error('Files failure'));
}

function getUrls(files) {
    const promises = []
    files.forEach(file => promises.push(file.getDownloadURL()))
    return Promise.all(promises);
}

我的Key.json位於我的功能文件夾內

Key.json

{
  "type": "service_account",
  "project_id": "…”,
  "private_key_id": “…”,
  "private_key": "-----BEGIN PRIVATE KEY——…”,
  "client_email": “…”,
  "client_id": “…”,
  "auth_uri": “…”,
  "token_uri": “…”,
  "auth_provider_x509_cert_url": “…”,
  "client_x509_cert_url": “…”
}

儲存規則

rules_version = '2';
service firebase.storage {
  match /b/{bucket}/o {
    match /{allPaths=**} {
      allow read, write: if true
    }
  }
}

執行getImages()函數輸出為:

console.log(files): [ [] ]
console.error('Files failure'): Files failure

請問我在做什么錯?

我遇到的第一個也是主要問題是與Google Cloud Service的連接,這意味着:

  1. 我從Firebase Admin生成了一個全新的私鑰

Firebase項目 項目設定 產生新金鑰

  1. 下載文件並作為我的新Key.json確定我的項目

  2. 然后是最棘手的部分。 根據Google的文檔

您可以將Admin SDK返回的存儲桶引用與正式的Google Cloud Storage客戶端庫結合使用,以上傳,下載和修改與Firebase項目關聯的存儲桶中的內容。 請注意,使用Firebase Admin SDK時不必認證Google Cloud Storage庫。 Admin SDK返回的存儲桶引用已通過用於初始化Firebase應用程序的憑據進行了身份驗證。

這意味着,如果您在本地運行服務( npm run shell ),則需要實例化firebase-admin

var serviceAccount = require("./key.json");
var admin = require("firebase-admin");

admin.initializeApp({
    credential: admin.credential.cert(serviceAccount),
    databaseURL: "https://<my_project>.firebaseio.com"
});

然后打電話

const bucket = admin.storage().bucket('<my_bucket>.appspot.com')

您將准備訪問您的文件。 當直接通過部署或從雲控制台訪問google函數時,訪問存儲不需要admin初始化或密鑰本身(例如問題中第一個公開的index.js ,只需將代碼轉換為類似

const {Storage} = require('@google-cloud/storage');
...
const storage = new Storage({
    projectId: '<my_id>',
});

const bucket = storage.bucket('<my_bucket>')
...

關於Mayeru所說的話:

您已將目錄指定為“ / images”,但應將其指定為“ images /”

"images/"可用於查詢prefix參數,而不是directory 這個例子展示了它的工作原理,就像它對 Google文檔的引用一樣。

以下代碼進行了一些許諾調整,並為Android解析了JSON數據,它們的工作原理很吸引人。 本地和遠程。

index.js

var serviceAccount = require("./key.json");
const functions = require('firebase-functions');

const images = require('./images.js');

var admin = require("firebase-admin");

admin.initializeApp({
    credential: admin.credential.cert(serviceAccount),
    databaseURL: "https://<my_project>.firebaseio.com"
});

const bucket = admin.storage().bucket('<my_bucket>.appspot.com')

exports.getImages = functions.https.onRequest((request, response) => {
    images.getImages(bucket)
        .then(urls => response.status(200).send({ data: { urls } }))
        .catch(err => console.error(err));
})

images.js

module.exports = {
    getImages
}

const query = {
    directory: 'images'
};

function getImages(bucket) {
    return bucket.getFiles(query)
        .then(response => getUrls(response))
        .catch(err => console.error(err));
}

function getUrls(response) {
    const promises = []
    response.forEach( files => {
        files.forEach (file => {
            promises.push(getSignedUrl(file));
        });
    });
    return Promise.all(promises).then(result => getParsedUrls(result));
}

function getSignedUrl(file) {
    return file.getSignedUrl({
        action: 'read',
        expires: '09-01-2019'
    })
}

function getParsedUrls(result) {
    return JSON.stringify(result.map(mediaLink => createMedia(mediaLink)));
}

function createMedia(mediaLink) {
    const reference = {};
    reference.mediaLink = mediaLink[0];
    return reference;
}

這肯定會列出您存儲桶中images文件夾下的所有文件,並訪問它們的簽名下載URL,這些URL將通過Fresco庫呈現。 最后但並非最不重要的一點是,將顯示下載URL,但是要直接在其上發出GET請求,則需要調整存儲桶權限。 無論如何,這種“權限問題”是另一個主題,您可能還會在堆棧溢出時找到如何做的事情。

日志顯示:

[[]] // this is the "files" you retrieved.
Files failure 

如您所見,您沒有檢索任何文件,因此為什么它無法從空數組獲取URL的調用失敗。

您已將目錄指定為“ / images”,但應將其指定為“ images /”

那應該能夠檢索正確的文件夾。

另外, nodejs lib documentation上的“ file”對象不支持函數“ getDownloadURL()”。 您可能正在尋找getSignedUrl嗎?

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM