gpt4 book ai didi

javascript - 从多个位置删除相同的值 Firebase 函数

转载 作者:行者123 更新时间:2023-12-03 23:58:37 26 4
gpt4 key购买 nike

我有一个 firebase 功能,可以在 24 小时后删除旧消息,如我的旧问题 here .我现在只将 messageIds 存储在用户下的数组中,这样路径是:/User/objectId/myMessages,然后是 myMessages 下所有 messageIds 的数组。 24 小时后,所有消息都会被删除,但用户个人资料下的 iD 会保留在那里。有没有办法继续该功能,以便它还从用户帐户下的数组中删除 messageIds?

我是 Firebase 函数和 javascript 的新手,所以我不知道该怎么做。感谢所有帮助!

最佳答案

@frank-van-puffelen's accepted answer为基础在旧问题上,现在这将作为同一原子删除操作的一部分从发件人的用户数据中删除消息 ID,而不会为每条删除的消息触发云函数。

方法一:重构并发

在能够使用此方法之前,您必须重新构造 /User/someUserId/myMessages 中存储条目的方式。关注 best practices对于并发数组如下:

{
"/User/someUserId/myMessages": {
"-Lfq460_5tm6x7dchhOn": true,
"-Lfq483gGzmpB_Jt6Wg5": true,
...
}
}

这允许您将以前的函数修改为:

// Cut off time. Child nodes older than this will be deleted.
const CUT_OFF_TIME = 24 * 60 * 60 * 1000; // 2 Hours in milliseconds.

exports.deleteOldMessages = functions.database.ref('/Message/{chatRoomId}').onWrite(async (change) => {
const rootRef = admin.database().ref(); // needed top level reference for multi-path update
const now = Date.now();
const cutoff = (now - CUT_OFF_TIME) / 1000; // convert to seconds
const oldItemsQuery = ref.orderByChild('seconds').endAt(cutoff);
const snapshot = await oldItemsQuery.once('value');
// create a map with all children that need to be removed
const updates = {};
snapshot.forEach(messageSnapshot => {
let senderId = messageSnapshot.child('senderId').val();
updates['Message/' + messageSnapshot.key] = null; // to delete message
updates['User/' + senderId + '/myMessages/' + messageSnapshot.key] = null; // to delete entry in user data
});
// execute all updates in one go and return the result to end the function
return rootRef.update(updates);
});

方法二:使用数组

警告:这种方法会成为并发问题的牺牲品。如果用户要在删除操作期间发布新消息,则可以在评估删除时删除它的 ID。尽可能使用方法 1 来避免这种情况。

此方法假定您的 /User/someUserId/myMessages对象看起来像这样(一个普通数组):

{
"/User/someUserId/myMessages": {
"0": "-Lfq460_5tm6x7dchhOn",
"1": "-Lfq483gGzmpB_Jt6Wg5",
...
}
}

对于这个数据结构,我能想到的最精简、最具成本效益的防冲突功能如下:

// Cut off time. Child nodes older than this will be deleted.
const CUT_OFF_TIME = 24 * 60 * 60 * 1000; // 2 Hours in milliseconds.

exports.deleteOldMessages = functions.database.ref('/Message/{chatRoomId}').onWrite(async (change) => {
const rootRef = admin.database().ref(); // needed top level reference for multi-path update
const now = Date.now();
const cutoff = (now - CUT_OFF_TIME) / 1000; // convert to seconds
const oldItemsQuery = ref.orderByChild('seconds').endAt(cutoff);
const snapshot = await oldItemsQuery.once('value');
// create a map with all children that need to be removed
const updates = {};
const messagesByUser = {};
snapshot.forEach(messageSnapshot => {
updates['Message/' + messageSnapshot.key] = null; // to delete message

// cache message IDs by user for next step
let senderId = messageSnapshot.child('senderId').val();
if (!messagesByUser[senderId]) { messagesByUser[senderId] = []; }
messagesByUser[senderId].push(messageSnapshot.key);
});

// Get each user's list of message IDs and remove those that were deleted.
let pendingOperations = [];
for (let [senderId, messageIdsToRemove] of Object.entries(messagesByUser)) {
pendingOperations.push(admin.database.ref('User/' + senderId + '/myMessages').once('value')
.then((messageArraySnapshot) => {
let messageIds = messageArraySnapshot.val();
messageIds.filter((id) => !messageIdsToRemove.includes(id));
updates['User/' + senderId + '/myMessages'] = messageIds; // to update array with non-deleted values
}));
}
// wait for each user's new /myMessages value to be added to the pending updates
await Promise.all(pendingOperations);

// execute all updates in one go and return the result to end the function
return ref.update(updates);
});

关于javascript - 从多个位置删除相同的值 Firebase 函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59473701/

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