当前位置: 首页 > 知识库问答 >
问题:

谷歌云功能--为什么bucket总是返回文件的空数组?

宰父夕
2023-03-14

我正在尝试访问存储在我的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

{
  "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

请问我在这里做错了什么?

共有1个答案

史劲
2023-03-14

我遇到的第一个也是主要的问题是与我的Google云服务连接,这意味着:

  1. 我从Firebase Admin生成了一个全新的私钥

下载的文件,并将项目作为新的key.json确定下来

您可以使用Admin SDK返回的bucket引用以及官方的Google Cloud Storage客户端库来上传、下载和修改与Firebase项目相关联的bucket中的内容。请注意,在使用Firebase Admin SDK时,您不必对Google云存储库进行身份验证。管理SDK返回的bucket引用已经通过了用于初始化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/”可用于查询前缀参数,而不是目录。这个例子展示了它是如何工作的,就像它对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,以便用fresco等库呈现。最后,但并非最不重要的是,下载URL将被公开,但是直接在其上发出get请求将需要调整您的bucket权限。无论如何,这个“权限”是另一个主题,您可能会发现如何在堆栈溢出也这样做。

 类似资料:
  • 尝试从web执行云函数终结点时,我收到以下错误: 我遵循了这个教程:https://github.com/GoogleCloudPlatform/python-docs-samples/blob/master/functions/helloworld/main.py 按此处所述调用函数时:https://cloud.google.com/functions/docs/writing/http,我收

  • 我一直在使用Chromium谷歌语音API,最近我改用谷歌云语音API。自从Google云语音API发布以来,其性能在识别准确率方面似乎有所下降。此外,我还看到越来越多的“空结果”返回音频流。 我同时将音频流传输到多个不同的服务,谷歌云语音API返回空结果,而其他一些服务返回转录文本。让我想知道Chromium语音API和Google Cloud语音API的工作方式是否有任何改变? 我验证了音频的

  • 我正在开发google云语音api,我用我的flac文件尝试了他们的api,但他们只是转录了我的flac格式文件的一部分。我能对我的文件做些什么使它完美地工作吗。我试着在他们的链接上测试他们的api。我在请求正文中传递这个 {“audio”:{“uri”:“gs://kami1994/file-1506682082651.flac”},“config”:{“encoding”:“flac”,“la

  • 问题内容: 在CSS中定义时,总是返回空。 但是,如果您在该元素中设置样式,则可以获取style.display详细信息。 我的问题不同。 内联样式不是编码的好方法。因此,我们总是在CSS中分配样式。但是,为什么在提供style属性而不是通过element 时却显示为空?JavaScript是否特别无法读取style属性? 您可以在下面检查,即使我提供了,所有样式属性都为空。 为什么? 问题答案:

  • 刚刚完成Hello World谷歌云功能教程,收到以下响应头:

  • 所以我试图返回一个对象数组。我想列出所有的对象在谷歌云存储使用云函数内的特定桶。下面是我到目前为止。它返回和未处理的promise。 我写了一个类似的函数,它返回来自Firebase fi恢复的文档数组。 这是登录到控制台时返回的内容。我想在调用cloud函数列出bucket中的对象时显示相同的结果。 https://firebasestorage.googleapis.com/v0/b/kais