当从实时数据库中删除对象时,Firebase 函数(用 NodeJS 编写)从 Cloud Storage 中删除文件

Posted

技术标签:

【中文标题】当从实时数据库中删除对象时,Firebase 函数(用 NodeJS 编写)从 Cloud Storage 中删除文件【英文标题】:Firebase function (written in NodeJS) to delete file from Cloud Storage when an object is removed from Realtime Database 【发布时间】:2018-01-03 12:19:26 【问题描述】:

我是 NodeJS 的新手,我正在尝试为 Cloud Functions for Firebase 编写下一个方法。

我想要达到的目标:

    当用户从 Firebase DB 中移除照片对象时,该函数应该被触发; 代码应从 Storage 中删除与 Photo obj 对应的文件对象。

这些是我的 Firebase 数据库结构:

照片/userUID/photoUID


"dateCreated":      "2017-07-27T16:40:31.000000Z",
"isProfilePhoto":   true,
"isSafe":           true,
"uid":              "photoUID",
"userUID":          "userUID"

以及 Firebase 存储格式:

照片/userUID/photoUID.png

以及我正在使用的 NodeJS 代码:

    const functions = require('firebase-functions')
    const googleCloudStorage = require('@google-cloud/storage')(keyFilename: 'firebase_admin_sdk.json' )
    const admin = require('firebase-admin')
    const vision = require('@google-cloud/vision')();

    admin.initializeApp(functions.config().firebase)

    exports.sanitizePhoto = functions.database.ref('photos/userUID/photoUID')
        .onDelete(event => 

            let photoUID = event.data.key
            let userUID = event.data.ref.parent.key

            console.log(`userUID: $userUID, photoUID: $photoUID`);

            if (typeof photoUID === 'undefined' || typeof userUID === 'undefined') 
                console.error('Error while sanitize photo, user uid or photo uid are missing');
                return
            

            console.log(`Deleting photo: $photoUID`)

            googleCloudStorage.bucket(`photos/$userUID/$photoUID.png`).delete().then(() => 
                console.log(`Successfully deleted photo with UID: $photoUID, userUID : $userUID`)
            ).catch(err => 
                console.log(`Failed to remove photo, error: $err`)
            );

        );

当我运行它时,我得到下一个错误:“ApiError: Not found”

我认为这部分代码是导致问题的原因:

googleCloudStorage.bucket(`photos/$userUID/$photoUID.png`).delete()

提前感谢您的支持和耐心。

【问题讨论】:

@Jay 我做了必要的更改。 【参考方案1】:

找到问题,这里是适合我的代码:

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

实时数据库:

exports.sanitizePhoto = functions.database.ref('photos/userUID/photoUID').onDelete(event => 

        let photoUID = event.data.key
        let userUID = event.data.ref.parent.key

        console.log(`userUID: $userUID, photoUID: $photoUID`);

        if (typeof photoUID === 'undefined' || typeof userUID === 'undefined') 
            console.error('Error while sanitize photo, user uid or photo uid are missing');
            return
        

        console.log(`Deleting photo: $photoUID`)

        const filePath = `photos/$userUID/$photoUID.png`
        const bucket = googleCloudStorage.bucket('myBucket-12345.appspot.com')
        const file = bucket.file(filePath)

        file.delete().then(() => 
            console.log(`Successfully deleted photo with UID: $photoUID, userUID : $userUID`)
        ).catch(err => 
            console.log(`Failed to remove photo, error: $err`)
        );

    );

这里还有相同的代码,但用于 Firestore(不确定它是否有效,因为我不是 NodeJS 开发人员,也没有实际测试过):

exports.sanitizePhoto = functions.firestore.document('users/userUID/photos/photoUID').onDelete((snap, context) =>

    const deletedValue = snap.data();

    let photoUID = context.params.photoUID 
    let userUID = context.params.userUID

    console.log(`userUID: $userUID, photoUID: $photoUID`);

    if (typeof photoUID === 'undefined' || typeof userUID === 'undefined') 
        console.error('Error while sanitize photo, user uid or photo uid are missing');
        return
    

    console.log(`Deleting photo: $photoUID`)

    const filePath = `photos/$userUID/$photoUID.png`
    const bucket = googleCloudStorage.bucket('myBucket-12345.appspot.com')
    const file = bucket.file(filePath)

    file.delete().then(() => 
        console.log(`Successfully deleted photo with UID: $photoUID, userUID : $userUID`)
    ).catch(err => 
        console.error(`Failed to remove photo, error: $err`)
    );

);

您还可以注意到我的路径从:

photos/userUID/photoUID 

到:

users/userUID/photos/photoUID

【讨论】:

谢谢,我收到一个参考错误:googleCloudStorage 未定义。我想知道我是否忘记为 googleCloud Storage 安装带有 nom 的东西。有什么想法吗? 已修复,我已将 googleCloudStorage 安装到项目目录中,而不是函数目录中。 值得注意的是,根据最佳实践 (here),不建议将 userID 放在文件名中。 如何检查文件是否存在(nodejs)?删除时出现“错误:没有这样的对象”【参考方案2】:

试试这个代码

const gcs  = require('@google-cloud/storage')()

    const fileBucketPush = 'Storage bucket.appspot.com'; // The Storage bucket that contains the file.
    const filePathPush = 'folder/'+nameImage; // File path in the bucket.
    vision.detectSafeSearch(gcs.bucket(fileBucketPush).file(filePathPush))
      .then((results) => 
       ..///

      )
      .catch((err) => 
        console.error('ERROR:', err);
      );

您启用 Cloud Vision API 吗?

【讨论】:

以上是关于当从实时数据库中删除对象时,Firebase 函数(用 NodeJS 编写)从 Cloud Storage 中删除文件的主要内容,如果未能解决你的问题,请参考以下文章

每次在 firebase 实时数据库中添加新孩子时使用 firebase 函数发送推送通知不起作用

Flutter - 从特定值中删除数据,Firebase 实时数据库 [重复]

useContext 未在子组件中显示更新的状态(当从全局文件中的 useEffect 挂钩中的 firebase 检索数据时)

如何从firebase实时数据库中删除?

在添加或删除的 Firebase Firestore 数据中重复 RecyclerView 项

如何在 firebase 实时数据库中删除我的数据?