简体   繁体   English

Firebase 云函数 onDelete 问题 - 数据库

[英]Firebase Cloud Functions onDelete problem - Database

I have the following structure in the Firebase database, where RoomsTemplate is a subscription room.我在 Firebase 数据库中有以下结构,其中RoomsTemplate是订阅室。 If someone signs up for the Users node, another function (onWrite) increases the value of CountUsers .如果有人注册Users节点,另一个 function (onWrite) 会增加CountUsers的值。

在此处输入图像描述

and the following function decreases the value of CountUsers when users unsubscribe from node Users .并且以下 function 会在用户退订节点Users时减小CountUsers的值。

exports.recountUsers = functions.database.ref('/RoomsTemplate/{id}/CountUsers').onDelete(async (snap) => {
  const counterRef = snap.ref;
  const collectionRef = counterRef.parent.child('Users');
  const messagesData = await collectionRef.once('value');
  return await counterRef.set(messagesData.numChildren());
});

The problem is that, if I want to delete the main node of the RoomsTemplate , in this case问题是,如果我想删除RoomsTemplate的主节点,在这种情况下

-MBb2ZKj-pquagHBqguS -MBb2ZKj-pquagHBqguS

the onDelete function won't let me delete it, but it will update the CountUsers: 0 again. onDelete function 不会让我删除它,但它会再次更新CountUsers: 0 Try deleting the Barrio:"Barcelona" node with another function first and then verify and delete the main node.尝试先用另一个 function 删除Barrio:"Barcelona"节点,然后验证并删除主节点。

exports.recountUsers = functions.database.ref('/RoomsTemplate/{id}/CountUsers').onDelete(async (snap) => {
  const counterRef = snap.ref;
  const collectionRef = counterRef.parent.child('Users');  
  const messagesData = await collectionRef.once('value');

  const Barrio = await counterRef.parent.child('Barrio').once('value');

   if(Barrio.numChildren() === 0){
     return await counterRef.remove();
   }else if(Barrio.numChildren() > 0){
     return await counterRef.set(messagesData.numChildren());
   }else{
     return null;
   } 

});

But I still have the same existence problem.但我仍然有同样的存在问题。 How can I permanently delete the main node (-MBb2ZKj-pquagHBqguS), without executing the onDelete function?如何在不执行 onDelete function 的情况下永久删除主节点 (-MBb2ZKj-pquagHBqguS)?

My first thought is that you've modeled yourself into a problem here, by not following the guidance to keep your data structure flat.我的第一个想法是,您在这里将自己建模为一个问题,没有遵循保持数据结构平坦的指导。 My recommended solution based on that is to further denormalize the data, and pull the counts into a separate top-level list.基于此,我推荐的解决方案是进一步非规范化数据,并将计数拉入单独的顶级列表。 In fact, I see three top-level lists here:事实上,我在这里看到了三个顶级列表:

RoomsTemplate
  $roomid: { Barrio: "..." }
},
RoomsTemplate_users: {
  $roomid: { "uid1" true, "uid2": true }
},
RoomsTemplate_usercounts: {
  $roomid: 2
}

Alternatively, within your current data structure, you can check if the room still exists before writing the counter.或者,在您当前的数据结构中,您可以在编写计数器之前检查房间是否仍然存在。 For example for the first Cloud Function that would look like:例如,对于第一个 Cloud Function,它看起来像:

exports.recountUsers = functions.database.ref('/RoomsTemplate/{id}/CountUsers').onDelete(async (snap) => {
  const counterRef = snap.ref;
  const roomRef = counterRef.parent;
  const roomSnapshot = await roomRef.once("value");
  if (roomSnapshot.exists()) {
    const messagesData = roomSnapshot.child("Users");
    await counterRef.set(messagesData.numChildren());
  }
  return true;
});

Since Cloud Functions execute asynchronously after the original write has completed, this once('value' (like the one you have for the collectionRef already) will always get the current snapshot from the database, which is where the room has disappeared.由于 Cloud Functions 在原始写入完成后异步执行,因此 this once('value' (就像您已经拥有的collectionRef一样)将始终从数据库中获取当前快照,这就是房间消失的地方。

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

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