gpt4 book ai didi

javascript - 云HTTPS函数: returning a Promise which is inside a Promisee

转载 作者:行者123 更新时间:2023-12-02 21:32:25 24 4
gpt4 key购买 nike

我目前正在使用 Firebase 开发 HTTPS 云功能,包括删除我的 Android 用户请求的帖子。

总体思路

工作流程是(整个代码在此SO问题的末尾可用):1)Firebase检查用户身份( admin.auth().verifyIdToken ); 2) Firestore 从必须删除的帖子中获取数据 ( deleteDbEntry.get().then() ) ; 3) 云存储准备删除获取数据中找到的文件(.file(filePath).delete()); 4) Firestore 准备一批删除帖子 ( batch.delete(deleteDbEntry); ) 并使用获取的数据更新喜欢/不喜欢的内容 ( batch.update(updateUserLikes, ) ; 5) 执行删除文件和批处理的 promise ( return Promise.all([deleteFile, batch_commit]) )。

预期行为

我想检查用户身份。如果成功,则使用 Firebase 获取请求的帖子以删除数据。如果成功,我希望在同一个 promise 中执行 Firestore 批处理和云存储文件删除(这就是我使用 Promise.all([deleteFile, batch_commit]).then() 的原因)。如果身份检查失败,或者数据获取失败,或者批处理失败,我想告诉Android应用程序。如果一切成功,同上。

由于所有这些操作都在 Cloud HTTPS Function 中,因此我必须返回一个 promise 。我认为,这个 promise 将对应于所有这些操作(如果它们成功),或者如果至少有一个操作不成功(?),则对应于错误(?)。

实际行为

目前,我只是返回 Firebase 用户身份检查的 promise 。

我的问题和我的问题

我无法从实际行为转向预期行为,因为:

  1. 我觉得自己不太清楚是否应该在这个 Cloud HTTPS Function 中返回“所有这些操作都成功,或者至少有一个不成功”对应的 Promise

  2. 由于这些操作是嵌套的(批量中存在的 Firestorage 文件删除 + Firestore 后删除除外),我无法返回类似 Promise.all() 的内容.

我的问题

您能告诉我我是否正确(第 1 点),如果不正确:我该怎么办?如果是:由于第 2 点,我该怎么做?

整个 Firebase Cloud HTTPS 函数代码

注意:我已经删除了输入数据控件以使我的代码更易于理解。

exports.deletePost = functions.https.onCall((data, context) => {

return admin.auth().verifyIdToken(idToken)
.then(function(decodedToken) {
const uid = decodedToken.uid;

const type_of_post = data.type_of_post;
const the_post = data.the_post;
const deleteDbEntry = admin_firestore.collection('list_of_' + type_of_post).doc(the_post);
const promise = deleteDbEntry.get().then(function(doc) {

const filePath = type_of_post + '/' + uid + '/' + data.stored_image_name;
const deleteFile = storage.bucket('android-f.appspot.com').file(filePath).delete();

const batch = admin.firestore().batch();
batch.delete(deleteDbEntry);
if(doc.data().number_of_likes > 0) {
const updateUserLikes = admin_firestore.collection("users").doc(uid);
batch.update(updateUserLikes, "likes", FieldValue.increment(-doc.data().number_of_likes));
}
const batch_commit = batch.commit();

return Promise.all([deleteFile, batch_commit]).then(function() {
return 1;
}).catch(function(error) {
console.log(error);
throw new functions.https.HttpsError('unknown', 'Unable to delete the post. (2)');
});

}).catch(function(error) {
console.log(error);
throw new functions.https.HttpsError('unknown', 'Unable to delete the post. (1)');
});

return promise;


}).catch(function(error) {
console.log(error);
throw new functions.https.HttpsError('unknown', 'An error occurred while verifying the token.');
});
});

最佳答案

您应该注意,您实际上正在定义 Callable Cloud Function而不是 HTTPS one ,既然你这样做了:

exports.deletePost = functions.https.onCall((data, context) => {..});

可调用云函数相对于 HTTPS 的优势之一是它“自动反序列化请求正文并验证身份验证 token ”。

因此,您可以简单地使用 context.auth.uid; 获取用户 uid

<小时/>

现在,关于“编排”不同调用的方式,恕我直言,您应该链接异步 Firebase 方法(Firestore 的方法和 Cloud Storage 的方法)返回的不同 Promise,如下所示:

exports.deletePost = functions.https.onCall((data, context) => {

//....
const uid = context.auth.uid;

let number_of_likes;

const type_of_post = data.type_of_post;
const the_post = data.the_post;
const deleteDbEntry = admin_firestore.collection('list_of_' + type_of_post).doc(the_post);

return deleteDbEntry.get()
.then(doc => {
number_of_likes = doc.data().number_of_likes;
const filePath = type_of_post + '/' + uid + '/' + data.stored_image_name;
return storage.bucket('android-f.appspot.com').file(filePath).delete();

})
.then(() => {

const batch = admin.firestore().batch();
batch.delete(deleteDbEntry);

if (number_of_likes > 0) {
const updateUserLikes = admin_firestore.collection("users").doc(uid);
batch.update(updateUserLikes, "likes", FieldValue.increment(-doc.data().number_of_likes));
}

return batch.commit();

}).catch(function (error) {
console.log(error);
throw new functions.https.HttpsError('....', '.....');
});

});

我认为在您的情况下使用 Promise.all() 不会带来任何兴趣,因为,正如所解释的 here ,“如果任何传入的 Promise 被拒绝,Promise.all 会以被拒绝的 Promise 的值异步拒绝,无论其他 Promise 是否已解决”。

在撰写本文时,无法将对不同 Firebase 服务的所有异步调用分组到一个原子操作中。

即使最后的批量写入是原子的,也可能会发生 Cloud Storage 中的文件被正确删除但对 Firestore 的批量写入未执行的情况,例如因为 Firestore 服务出现问题。

<小时/>

另外,请注意,您只需要 Promise 链末尾的一个异常处理程序。如果您想区分异常的原因,通过向前端发送不同的错误消息的方式,您可以使用此 article 中介绍的方法。 .

本文展示了如何定义不同的自定义错误类(派生自标准内置错误对象),这些类用于检查异常处理程序中的错误类型。

关于javascript - 云HTTPS函数: returning a Promise which is inside a Promisee,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60587876/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com