【问题标题】:Cloud Storage for Firebase access error "admin.storage(...).ref is not a function"Cloud Storage for Firebase 访问错误“admin.storage(...).ref 不是函数”
【发布时间】:2018-05-28 08:30:54
【问题描述】:

我正在使用 Cloud Storage for Firebase,但不知道如何访问存储文件

根据https://firebase.google.com/docs/storage/web/start 官方指南和https://firebase.google.com/docs/storage/web/create-reference,此代码应返回根引用

let admin = require('firebase-admin')
admin.initializeApp({...})
let storageRef = admin.storage().ref()

但它会抛出一个错误说

TypeError: admin.storage(...).ref 不是函数

package.json

{
  "name": "functions",
  "description": "Cloud Functions for Firebase",
  "scripts": {...},
  "dependencies": {
    "@google-cloud/storage": "^1.5.1",
    "firebase": "^4.8.0",
    "firebase-admin": "~5.4.2",
    "firebase-functions": "^0.7.1",
    "pdfkit": "^0.8.3",
    "uuid": "^3.1.0"
  },
  "private": true
}

节点-v => v7.7.4

我的最终目标是下载文件或将 pdf 文件上传到存储。

【问题讨论】:

  • 你在功能上吗?如果是,请使用bucket = admin.storage().bucket(),功能管理员不使用 Web api
  • 感谢您的回复,是的,我可以通过这种方式访问​​存储桶,并且可以使用bucket.file('images/snow.jpg') 访问文件,但我想返回/下载文件以响应云功能。可以指导一下吗?
  • 我试过bucket.file('images/snow.jpg').getDownloadURL(),但它说bucket.file(...).getDownloadURL is not a function
  • 因为它不是。查看可用功能:cloud.google.com/nodejs/docs/reference/storage/1.4.x/File
  • 嘿 .. 我不断收到 .. 错误:没有client_email 就无法签署数据。在哪里可以配置 client_email ?

标签: node.js firebase firebase-storage firebase-admin


【解决方案1】:

您正在使用 Cloud Functions 和 Firebase Admin SDK 来尝试访问您的存储桶。您引用的入门指南正在讨论使用 Firebase 的 Web API 而不是管理员的客户端 Web 应用程序。那里的功能不同,因为它使用不同的 SDK(即使它们的名称相同)。

您尝试访问的Storage 对象没有ref() 函数,只有appbucket()

https://firebase.google.com/docs/reference/admin/node/admin.storage

尝试直接使用 Google Cloud API:

https://cloud.google.com/storage/docs/creating-buckets#storage-create-bucket-nodejs

-

编辑: 这个编辑只是为了停止用两年前的帖子吓唬人们。截至 2020 年 5 月,上述答案仍然适用。

【讨论】:

【解决方案2】:

如果您只是想临时链接到 Cloud Storage Bucket 中文件夹中的所有图像,以下代码 sn-p 将实现它。在这个例子中,我查询了images/userId文件夹下的所有图片。

exports.getImagesInFolder = functions.https.onRequest(async (req, res) => {
    const storageRef = admin.storage().bucket('gs://{YOUR_BUCKET_NAME_HERE}');
    const query = {
        directory: `images/${req.body.userId}` // query for images under images/userId
    };
    
    const [files] = await storageRef.getFiles(query)
    const urls = await Promise.all(files.map(file => file.getSignedUrl({
        action: "read",
        expires: '04-05-2042' // this is an arbitrary date
    })))

    return res.send({ urls })
})

API 文档:

PS:请记住,这可能允许任何人传递userId 并查询此特定用户的所有图像。

【讨论】:

    【解决方案3】:

    在下面的示例中,我从名为“images”的现有 Firestore 集合中提取图像引用。我将“图像”集合与“帖子”集合交叉引用,这样我只能获得与某个帖子相关的图像。这不是必需的。

    Docs for getSignedUrl()

    const storageBucket = admin.storage().bucket( 'gs://{YOUR_BUCKET_NAME_HERE}.appspot.com' )
    const getRemoteImages = async() => {
        const imagePromises = posts.map( (item, index) => admin
            .firestore()
            .collection('images')
            .where('postId', '==', item.id)
            .get()
            .then(querySnapshot => {
                // querySnapshot is an array but I only want the first instance in this case
                const docRef = querySnapshot.docs[0] 
                // the property "url" was what I called the property that holds the name of the file in the "posts" database
                const fileName = docRef.data().url 
                return storageBucket.file( fileName ).getSignedUrl({
                    action: "read",
                    expires: '03-17-2025' // this is an arbitrary date
                })
            })
            // chained promise because "getSignedUrl()" returns a promise
            .then((data) => data[0]) 
            .catch(err => console.log('Error getting document', err))
        )
        // returns an array of remote image paths
        const imagePaths = await Promise.all(imagePromises)
        return imagePaths
    }
    

    以下是合并的重要部分:

    const storageBucket = admin.storage().bucket( 'gs://{YOUR_BUCKET_NAME_HERE}.appspot.com' )
    const fileName = "file-name-in-storage" // ie: "your-image.jpg" or "images/your-image.jpg" or "your-pdf.pdf" etc.
    const remoteImagePath = storageBucket.file( fileName ).getSignedUrl({
        action: "read",
        expires: '03-17-2025' // this is an arbitrary date
    })
    .then( data => data[0] )
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-09-28
      • 2021-12-26
      • 2017-09-24
      • 1970-01-01
      • 2023-03-11
      • 2018-10-11
      • 2015-12-29
      • 2020-09-06
      相关资源
      最近更新 更多