【问题标题】:How do you return a 'success' message to the frontend using onFinalize?如何使用 onFinalize 向前端返回“成功”消息?
【发布时间】:2021-07-17 22:46:18
【问题描述】:

我目前正在使用带有 Firebase Javascript SDK 的 ReactJs 前端。它在后端使用 NodeJS 连接到 firebase-functions 存储模拟器。

通常我可以从我的前端调用一个functions.https.onCall(...)云函数(已经用nodejs设置)并收到一个promise,然后我可以正常使用前端的数据。

但是,在后端使用functions.storage.object().onFinalize(...),我试图强制某种方式在成功处理文件后向我的前端返回成功消息。

这是我尝试过的:

我的后端代码(Nodejs):

exports.processMedia = functions.storage.object().onFinalize(async (object) =>{
// Here I successfully process any uploaded images

// Issue - After the media has been processed, I'd like to return a message that can be used to update the UI. I've tried to return a new promise like so:

return new Promise((resolve, reject) =>{
        return resolve("Success");
    });
})

然后在我的 React UI 中,我尝试使用 httpsCallable('processMedia') 函数从后端捕获返回消息,因为我不知道如何尝试获取响应。

async processMedia(){
    const processMediaCallable = this.functions.httpsCallable('processMedia');
    return processMediaCallable;
}

然后我尝试从 promise 中注销值:

async function getProcessedMessage(){
    await firebase.processMedia().then((val) => {
        console.log(val);
    }); 
}

在我在 UI 中上传文件并且后端中的 processMedia() 已完成后,我在浏览器控制台中获得了 val 的此输出:

ƒ (data) {
      return _this.call(name, data, options || {});
    }

我正在尝试在此处输出成功消息。任何想法将不胜感激。谢谢。

【问题讨论】:

标签: javascript node.js firebase google-cloud-functions google-cloud-storage


【解决方案1】:

您不能从后台函数向客户端返回响应。当用户将任何文件上传到您的 Firebase 存储时,他们会收到成功响应,并且从该事件触发的函数与客户端无关。有一个使用 Firebase Realtime Database 的解决方法,您可以使用它来向用户发出响应。

用简单的步骤分解它:

  1. 将文件上传到 Firebase 存储
  2. 在客户端创建实时数据库监听器
  3. 在 Cloud Function 中完成所有处理后,在数据库中写入一些内容,然后将其交付给您的用户。

客户:

async function uploadFile() { 
  // upload to firebase storage
  const alertRef = firebase.database().ref(`alerts/${userID}`);
  alertRef.on('child_added', (snapshot) => {
    const data = snapshot.val();
    // Alert received from cloud function
    // Delete this alert from database
    snapshot.ref.set(null)
  });
}

云功能:

exports.processMedia = functions.storage.object().onFinalize(async (object) => { 
  // Process the file
  // Add alert in realtime database
  const alertRef = firebase.database().ref(`alerts/${userID}`).push()
  return alertRef.set({...}) // add any data you would like to pass to client side
})

child_added 事件会为每个现有的孩子触发一次,然后在每次将新的孩子添加到指定路径时再次触发。侦听器被传递一个包含新孩子数据的快照。

话虽如此,但请确保您不会多次使用相同的通知提醒用户。

【讨论】:

  • 您好,感谢您的回复。这说得通。我想我也可以使用 Cloud Firestore 来实现同样的目标,对吧?还是child_added 参数特定于实时数据库?我的项目大量使用 Cloud Firestore,如果可能,我想避免设置实时数据库。
  • @uponly 是的,你可以。 Firestore 也有 realtine 听众
猜你喜欢
  • 2021-09-01
  • 1970-01-01
  • 2016-09-19
  • 1970-01-01
  • 2020-07-02
  • 2018-04-24
  • 2023-03-25
  • 2017-09-28
  • 1970-01-01
相关资源
最近更新 更多