简体   繁体   English

Cloud Storage for Firebase 访问错误“admin.storage(...).ref is not a function”

[英]Cloud Storage for Firebase access error “admin.storage(…).ref is not a function”

I am working with Cloud Storage for Firebase and can't figure out how to to access storage files我正在使用 Cloud Storage for Firebase,但不知道如何访问存储文件

According to https://firebase.google.com/docs/storage/web/start official guide and https://firebase.google.com/docs/storage/web/create-reference this code should be returning root reference根据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()

But it throws an error saying但它抛出一个错误说

TypeError: admin.storage(...).ref is not a function类型错误:admin.storage(...).ref 不是函数

package.json包.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
}

node -v => v7.7.4节点 -v => v7.7.4

My end goal it to download files or upload a pdf file to storage.我的最终目标是下载文件或将 pdf 文件上传到存储。

You are using Cloud Functions and the Firebase Admin SDK to try and access your bucket.您正在使用 Cloud Functions 和 Firebase Admin SDK 来尝试访问您的存储桶。 The Getting Started guide you cited is talking about client sided Web Apps with the Web API for Firebase not the Admin one.您引用的入门指南讨论的是带有 Web API for Firebase 的客户端 Web 应用程序,而不是 Admin 应用程序。 The functionality there is different, because it uses a different SDK (even if their names are the same).那里的功能不同,因为它使用不同的 SDK(即使它们的名称相同)。

The Storage Object you are trying to access doesn't have the ref() functions, only app and bucket() .您尝试访问的Storage对象没有ref()函数,只有appbucket()

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

Try using the Google Cloud APIs directly:尝试直接使用 Google Cloud API:

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

- ——

EDIT: This edit is only to stop scaring people with an post from two years ago.编辑:此编辑只是为了停止用两年前的帖子吓唬人。 The answer above still applies as of May 2020.截至 2020 年 5 月,上述答案仍然适用。

In the below example, I am extracting image references from an existing Firestore collection called "images".在下面的示例中,我从名为“图像”的现有 Firestore 集合中提取图像引用。 I am cross referencing the "images" collection with the "posts" collection such that I only get images that relate to a certain post.我将“图像”集合与“帖子”集合交叉引用,这样我只能获得与某个帖子相关的图像。 This is not required.这不是必需的。

Docs for getSignedUrl() 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
}

Here is the important part consolidated:这是合并的重要部分:

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] )

If you simply want temporary links to all images in a folder in a Cloud Storage Bucket, the following code snippet will achieve it.如果您只想临时链接到 Cloud Storage Bucket 中某个文件夹中的所有图像,以下代码片段将实现它。 In this example, I query for all images under the folder images/userId .在此示例中,我查询文件夹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 Documentation: API 文档:

PS : Please keep in mind that this might allow anyone to pass a userId and query for all images for this specific user. PS :请记住,这可能允许任何人传递userId并查询此特定用户的所有图像。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM