从本地字典中删除值当 Firebase 子项被删除时,Swift。

huangapple go评论149阅读模式
英文:

Removing value from local Dictionary when firebase child deleted swift

问题

你好,我正在学习如何正确使用Firebase实时数据库。我正在构建一个应用程序,用户可以更改他们的工作地点(基地)。在我的个人设置控制器中,用户可以通过选择 pickerView 选择他们的基地。实时数据库得到了正确的更新。我有所有用户的列表以及每个基地的分开列表。问题出现在主视图控制器上。
我有一个集合视图,显示了我所在位置的用户列表。
我的目标是查看谁来到我的位置或离开我的位置。
我有两个函数,一个用于获取我的用户数据,确定我要显示的当前基地

func fetchCurrentUser() {

    if currentUser == nil {
        common.errorAlert("无法检索用户详细信息。")
        return
    }

    guard let userID = Auth.auth().currentUser?.uid else { return }

    ref.child(userID).observeSingleEvent(of: DataEventType.value) { (snapshot) in
        if !snapshot.exists() { return }
        let userDetailsData = snapshot.value as? NSDictionary
        self.id = userDetailsData?["id"] as? String ?? ""
        self.myBase = userDetailsData?["base"] as? String ?? ""
        self.indexBasePicker = userDetailsData?["baseIndex"] as? Int ?? 0
        self.headerPosition(self.indexBasePicker)
        if self.myBase != "" {
            self.fetchAllUsers()
        }
    }
}

第二个是获取我所在位置的所有用户:

func fetchAllUsers() {

    ref.child(myBase).observe(.childAdded, with: { (snapshot) in

        if let dictionary = snapshot.value as? [String: AnyObject] {
            let user = User(dictionary: dictionary)
            if  user.isAdmin == true {
                self.usersArray.append(user)
                self.reloadTeamCollectionView()
            }
        }
    })

    ref.child(myBase).observe(.childRemoved, with: { (snapshot) in

        if let dictionary = snapshot.value as? [String: AnyObject] {
            let user = User(dictionary: dictionary)

            for (index, userArray) in self.usersArray.enumerated() {
                if userArray.id == user.id {
                    print(index)
                    self.usersArray.remove(at: index)
                    self.reloadTeamCollectionView()
                }
            }
        }
    })

}

问题是当有人加入我的当前位置时,它会多次添加到列表中,有时应用程序会崩溃,显示索引超出范围的错误。

任何帮助将不胜感激。
我有两个引用:

let ref = Database.database().reference(withPath: "users")
let refOnline = Database.database().reference(withPath: "usersOnline")
let refOffline = Database.database().reference(withPath: "usersOffline")
这是当按下保存按钮时更新用户配置文件的方式:

func updateDatasIsOnline(online: Bool) {

    if currentUser == nil {
        // common.errorAlert("Error could not read user details")
        print("Error could not read user details")
        return
    }

    let filename = "profilePhoto"

    Storage.storage().reference().child(self.currentUser?.uid ?? "").child("profile_images").child(filename).downloadURL { (url, error) in
        guard let downloadURL = url else {
            common.errorAlert(error?.localizedDescription ?? "")
            return
        }

        let userValues = [
            "id": self.currentUser?.uid ?? "",
            "name": self.nameTextField.text ?? "",
            "committee": self.selectedCommitteeName,
            "position": self.positionTextField.text ?? "",
            "base": self.myBase,
            "baseIndex": self.basePickerPosition,
            "isAdmin": self.isAdmin,
            "isOnline": online,
            "email": self.emailTextField.text ?? "",
            "phone": self.reformatPhoneNumberForDataBase(self.phoneNumberTextField.text ?? ""),
            "iMessage": self.iMessageTextField.text ?? "",
            "whatsapp": self.reformatPhoneNumberForDataBase(self.whatsappTextField.text ?? ""),
            "fBMessenger": self.fBMessengerTextField.text ?? "",
            "profileImageUrl": downloadURL.absoluteString,
            "fileNumber": self.fileNbr
        ] as [String : Any]

        if online == true {
            self.ref.child(self.currentUser?.uid ?? "").updateChildValues(["isOnline" : true])
            self.refOnline.child(self.currentUser?.uid ?? "").setValue(userValues)
            self.refOffline.child(self.currentUser?.uid ?? "").removeValue()
        } else {
            self.ref.child(self.currentUser?.uid ?? "").updateChildValues(["isOnline" : false])
            self.refOffline.child(self.currentUser?.uid ?? "").setValue(userValues)
            self.refOnline.child(self.currentUser?.uid ?? "").removeValue()
        }
    }
}
英文:

Hello I am learning on how to properly use firebase realtime database. I am building an app where user can change their work locations (base). in my profile settings controller user choose their base via a pickerView. The real time database gets updated properly. I have the list of all users and seperate list per base . Where is get stuck is on the main view controller.
I have collection view that display a list of user of my own location.
My goal is to see who comes to my location or depart my location.
I have 2 functions one that fetch my own user datas . which determine the current base i want to dispaly

func fetchCurrentUser() {
        
        if currentUser == nil {
            common.errorAlert("Could not retrieve user details.")
            return
        }
        
        guard let userID = Auth.auth().currentUser?.uid else { return }
        
        ref.child(userID).observeSingleEvent(of: DataEventType.value) { (snapshot) in
            if !snapshot.exists() { return }
            let userDetailsData = snapshot.value as? NSDictionary
            self.id = userDetailsData?["id"] as? String ?? ""
            self.myBase = userDetailsData?["base"] as? String ?? ""
            self.indexBasePicker = userDetailsData?["baseIndex"] as? Int ?? 0
            self.headerPosition(self.indexBasePicker)
            if self.myBase != "" {
                self.fetchAllUsers()
            }
        }
    }

The second fetchallusers at my location:

func fetchAllUsers() {
        
        ref.child(myBase).observe(.childAdded, with: { (snapshot) in
            
            if let dictionary = snapshot.value as? [String: AnyObject] {
                let user = User(dictionary: dictionary)
                if  user.isAdmin == true {
                    self.usersArray.append(user)
                    self.reloadTeamCollectionView()
                }
            }
        })
        
        ref.child(myBase).observe(.childRemoved, with: { (snapshot) in
            
            if let dictionary = snapshot.value as? [String: AnyObject] {
                let user = User(dictionary: dictionary)
                
                for (index, userArray) in self.usersArray.enumerated() {
                    if userArray.id == user.id {
                        print(index)
                        self.usersArray.remove(at: index)
                        self.reloadTeamCollectionView()
                    }
                }
            }
        })
        
    }

the problem is when someone join my current location it gets added to the list , sometimes severaltimes. and when someone departs some time the app crashes with index out of range error

any help would be tremendously appreciated

.
"users" : {
"BdxqjmhjM0O3nV8uK9iC3HICHy32" : {
"availableStatus" : false,
"base" : "FRA",
"baseIndex" : 4,
"committee" : "★",
"email" : "",
"fBMessenger" : "",
"fileNumber" : "",
"iMessage" : "",
"id" : "BdxqjmhjM0O3nV8uK9iC3HICHy32",
"isAdmin" : true,
"isOnline" : true,
"name" : "",
"phone" : "",
"position" : "",
"profileImageUrl" : "https://firebasestorage.googleapis.com/v0/b/myunion-16f31.appspot.com/o/BdxqjmhjM0O3nV8uK9iC3HICHy32%2Fprofile_images%2FprofilePhoto?alt=media&token=e898f36f-7c3a-42a3-be4b-0a1b74cbd224",
"whatsapp" : ""
},
"DKfHhnwMgbOfGg3IpqG9QxlayxV2" : {
"availableStatus" : false,
"base" : "FRA",
"baseIndex" : 4,
"committee" : "★ Officers",
"email" : "",
"fBMessenger" : "",
"fileNumber" : "",
"iMessage" : "",
"id" : "DKfHhnwMgbOfGg3IpqG9QxlayxV2",
"isAdmin" : true,
"isOnline" : false,
"name" : "",
"phone" : "",
"position" : "",
"profileImageUrl" : "https://firebasestorage.googleapis.com/v0/b/myunion-16f31.appspot.com/o/DKfHhnwMgbOfGg3IpqG9QxlayxV2%2Fprofile_images%2FprofilePhoto?alt=media&token=204f4187-b508-405e-9835-bfdf5250019f",
"whatsapp" : ""
},
"GMupdPogn7YUag855TnWJkuzVzo1" : {
"availableStatus" : "Online",
"base" : "FRA",
"baseIndex" : 4,
"committee" : "Eap",
"email" : "lisa@lisa.com",
"fBMessenger" : "",
"fileNumber" : "u182874",
"iMessage" : "",
"id" : "GMupdPogn7YUag855TnWJkuzVzo1",
"isAdmin" : true,
"name" : "",
"phone" : "",
"position" : "",
"profileImageUrl" : "https://firebasestorage.googleapis.com/v0/b/myunion-16f31.appspot.com/o/GMupdPogn7YUag855TnWJkuzVzo1%2Fprofile_images%2FprofilePhoto?alt=media&token=8b3ec821-adad-47a9-943f-2cd4af50e436",
"whatsapp" : ""
},
"LS8plMZmlmSXsu9kVZxXRKsuPT13" : {
"availableStatus" : true,
"base" : "FRA",
"baseIndex" : 4,
"committee" : "Communication",
"email" : ",
"fBMessenger" : "",
"fileNumber" : "",
"iMessage" : "",
"id" : "LS8plMZmlmSXsu9kVZxXRKsuPT13",
"isAdmin" : true,
"isOnline" : true,
"name" : "",
"phone" : "",
"position" : "Chair",
"profileImageUrl" : "https://firebasestorage.googleapis.com/v0/b/myunion-16f31.appspot.com/o/LS8plMZmlmSXsu9kVZxXRKsuPT13%2Fprofile_images%2FprofilePhoto?alt=media&token=10ec728b-db42-485a-849d-0e2bcc0b3ba3",
"whatsapp" : "+33642056110"
},
"sqfl1FmeiiOuoq8dPePULYDEsnv2" : {
"availableStatus" : true,
"base" : "FRA",
"baseIndex" : 4,
"committee" : "",
"email" : "nonadmin@test.com",
"fBMessenger" : "",
"fileNumber" : "u182222",
"iMessage" : "",
"id" : "sqfl1FmeiiOuoq8dPePULYDEsnv2",
"isAdmin" : false,
"isOnline" : false,
"name" : "Nonadmin Test",
"phone" : "",
"position" : "",
"profileImageUrl" : "https://firebasestorage.googleapis.com/v0/b/myunion-16f31.appspot.com/o/sqfl1FmeiiOuoq8dPePULYDEsnv2%2Fprofile_images%2FprofilePhoto?alt=media&token=d4cfa840-954e-41fa-8490-23a5cd49fa56",
"whatsapp" : ""
}
},
"usersOffline" : {
"DKfHhnwMgbOfGg3IpqG9QxlayxV2" : {
"base" : "FRA",
"baseIndex" : 4,
"committee" : "★ Officers",
"email" : "merv",
"fBMessenger" : "",
"fileNumber" : "",
"iMessage" : "",
"id" : "",
"isAdmin" : true,
"isOnline" : false,
"name" : "Merv",
"phone" : "",
"position" : "Vice President",
"profileImageUrl" : "https://firebasestorage.googleapis.com/v0/b/myunion-16f31.appspot.com/o/DKfHhnwMgbOfGg3IpqG9QxlayxV2%2Fprofile_images%2FprofilePhoto?alt=media&token=204f4187-b508-405e-9835-bfdf5250019f",
"whatsapp" : ""
},
"sqfl1FmeiiOuoq8dPePULYDEsnv2" : {
"base" : "FRA",
"baseIndex" : 4,
"committee" : "",
"email" : "nonadmin@test.com",
"fBMessenger" : "",
"fileNumber" : "u182222",
"iMessage" : "",
"id" : "sqfl1FmeiiOuoq8dPePULYDEsnv2",
"isAdmin" : false,
"isOnline" : false,
"name" : "Nonadmin Test",
"phone" : "",
"position" : "",
"profileImageUrl" : "https://firebasestorage.googleapis.com/v0/b/myunion-16f31.appspot.com/o/sqfl1FmeiiOuoq8dPePULYDEsnv2%2Fprofile_images%2FprofilePhoto?alt=media&token=d4cfa840-954e-41fa-8490-23a5cd49fa56",
"whatsapp" : ""
}
},
"usersOnline" : {
"BdxqjmhjM0O3nV8uK9iC3HICHy32" : {
"base" : "FRA",
"baseIndex" : 4,
"committee" : "★ Officers",
"email" : "",
"fBMessenger" : "",
"fileNumber" : "",
"iMessage" : "",
"id" : "",
"isAdmin" : true,
"isOnline" : true,
"name" : "",
"phone" : "",
"position" : "",
"profileImageUrl" : "https://firebasestorage.googleapis.com/v0/b/myunion-16f31.appspot.com/o/BdxqjmhjM0O3nV8uK9iC3HICHy32%2Fprofile_images%2FprofilePhoto?alt=media&token=e898f36f-7c3a-42a3-be4b-0a1b74cbd224",
"whatsapp" : "+31620422185"
},
"LS8plMZmlmSXsu9kVZxXRKsuPT13" : {
"base" : "FRA",
"baseIndex" : 4,
"committee" : "Communication",
"email" : "",
"fBMessenger" : "",
"fileNumber" : "",
"iMessage" : "",
"id" : "LS8plMZmlmSXsu9kVZxXRKsuPT13",
"isAdmin" : true,
"isOnline" : true,
"name" : "",
"phone" : "",
"position" : "Chair",
"profileImageUrl" : "https://firebasestorage.googleapis.com/v0/b/myunion-16f31.appspot.com/o/LS8plMZmlmSXsu9kVZxXRKsuPT13%2Fprofile_images%2FprofilePhoto?alt=media&token=10ec728b-db42-485a-849d-0e2bcc0b3ba3",
"whatsapp" : "+33642056110"
}
}
}

i have 2 references

  let ref = Database.database().reference(withPath: "users")
let refOnline = Database.database().reference(withPath: "usersOnline")
let refOffline = Database.database().reference(withPath: "usersOffline")

this is how the user profile gets updated whe the save button is pressed

   func updateDatasIsOnline(online: Bool) {
if currentUser == nil {
//      common.errorAlert("Error could not read user details")
print("Error could not read user details")
return
}
let filename = "profilePhoto"
Storage.storage().reference().child(self.currentUser?.uid ?? "").child("profile_images").child(filename).downloadURL { (url, error) in
guard let downloadURL = url else {
common.errorAlert(error?.legibleLocalizedDescription ?? "")
return }
let userValues = [
"id": self.currentUser?.uid ?? "",
"name": self.nameTextField.text ?? "",
"committee": self.selectedCommitteeName,
"position": self.positionTextField.text ?? "",
"base": self.myBase,
"baseIndex": self.basePickerPosition,
"isAdmin": self.isAdmin,
"isOnline": online,
"email": self.emailTextField.text ?? "",
"phone": self.reformatPhoneNumberForDataBase(self.phoneNumberTextField.text ?? ""),
"iMessage": self.iMessageTextField.text ?? "",
"whatsapp": self.reformatPhoneNumberForDataBase(self.whatsappTextField.text ?? ""),
"fBMessenger": self.fBMessengerTextField.text ?? "",
"profileImageUrl": downloadURL.absoluteString,
"fileNumber": self.fileNbr
] as [String : Any]
if online == true {
self.ref.child(self.currentUser?.uid ?? "").updateChildValues(["isOnline" : true])
self.refOnline.child(self.currentUser?.uid ?? "").setValue(userValues)
self.refOffline.child(self.currentUser?.uid ?? "").removeValue()
} else {
self.ref.child(self.currentUser?.uid ?? "").updateChildValues(["isOnline" : false])
self.refOffline.child(self.currentUser?.uid ?? "").setValue(userValues)
self.refOnline.child(self.currentUser?.uid ?? "").removeValue()
}
}
}

答案1

得分: 0

似乎你在数据库内部传输了大量数据。这可能会很昂贵,同时也会消耗大量带宽。换句话说,根据当前的代码,如果用户的状态从在线变为离线,你的代码当前正在将所有用户数据从一个节点删除并重写到另一个节点,但实际上只需将在线标志从是更改为否即可。

我提出另一种可能在长期内更有帮助的选择,虽然它不是对现有代码的故障排除,但可能是一个更好的选择。

这里的想法是将用户数据保留在一个地方,只需更改子节点以反映不同的状态;不同的基地、在线/离线等。

要做到这一点,如果属性(子节点)符合查询的条件,你将收到通知。如果它不符合条件,你也将收到通知。

以下是提议的用户节点的样子。请注意,没有离线或在线节点,只有用户节点:

users
uid_0 //a users uid
base: "FRA"
name: "Frank"
online: "no"
uid_1
base: "ENG"
name: "Henry"
online: "yes"
uid_0 
base: "FRA"
name: "Leroy"
online: "yes"

从中你可以知道,Frank驻扎在法国,但不在线,Henry在英国并在线,Leroy也在法国并在线。

这是我的用户类和一个用于存储它们的数组:

class UserAndBaseClass {
    var uid = ""
    var name = ""
    var base = ""
    var online = ""
    
    init(withSnap: DataSnapshot) {
        self.uid = withSnap.key
        self.name = withSnap.childSnapshot(forPath: "name").value as? String ?? "No Name"
        self.base = withSnap.childSnapshot(forPath: "base").value as? String ?? "No Base"
        self.online = withSnap.childSnapshot(forPath: "online").value as? String ?? "Offline"
    }
}

var usersArray = [UserAndBaseClass]()

在第一部分的代码中,addedQuery 查询属于当前用户基地(FRA)的所有用户,并将它们存储在一个数组中。这将在用户节点上留下一个观察者,因此如果任何用户的基地变为FRA,它将符合该查询的参数,并且将被添加到查询中(因此触发.childAdded事件)。

第二部分 removedQuery 在所有符合查询的用户上建立了一个查询,如果基地变为FRA之外的其他内容,事件就会被触发,例如子节点被从查询参数中删除,然后.childRemoved事件被触发。

请注意,我们根本不使用.childChanged,因为前两个查询已经涵盖了它。

func observeUserBases() {
    
    let currentUserBase = "FRA"
    
    //获取当前用户基地FRA中的所有人。如果用户更改为此基地,也会触发此事件
    let usersRef = self.ref.child("users")
    let addedQuery = usersRef.queryOrdered(byChild: "base").queryEqual(toValue: currentUserBase)
    addedQuery.observe(.childAdded, with: { snapshot in
        let user = UserAndBaseClass(withSnap: snapshot)
        self.usersArray.append(user)
        print("\(user.name)已添加到您的基地")
    })
    
    //这将捕获任何被移除的用户,以及离开您的基地的用户
    let removedQuery = usersRef.queryOrdered(byChild: "base").queryEqual(toValue: "FRA")
    removedQuery.observe(.childRemoved, with: { snapshot in
        let keyToRemove = snapshot.key
        if let index = self.usersArray.firstIndex(where: { $0.uid == keyToRemove } ) {
            let name = self.usersArray[index].name
            print("\(name)已离开您的基地")
            self.usersArray.remove(at: index)
        }
    })
    
    let onlineQuery = usersRef.queryOrdered(byChild: "online").queryEqual(toValue: "yes")
    onlineQuery.observe(.childAdded, with: { snapshot in
        let keyOfChanged = snapshot.key
        let base = snapshot.childSnapshot(forPath: "base").value as? String ?? "No Base"
        
        if base == currentUserBase {
            if let index = self.usersArray.firstIndex(where: { $0.uid == keyOfChanged } ) {
                let name = self.usersArray[index].name
                print("\(name)现在在线")
                self.usersArray[index].online = "yes"
            }
        }
    })
    
    let offlineQuery = usersRef.queryOrdered(byChild: "online").queryEqual(toValue: "no")
    offlineQuery.observe(.childAdded, with: { snapshot in
        let keyOfChanged = snapshot.key
        let base = snapshot.childSnapshot(forPath: "base").value as? String ?? "No Base"
        
        if base == currentUserBase {
            if let index = self.usersArray.firstIndex(where: { $0.uid == keyOfChanged } ) {
                let name = self.usersArray[index].name
                print("\(name)已下线")
                self.usersArray[index].online = "no"
            }
        }
    })
}

最后两部分,onlineQueryofflineQuery 结构略有不同;每一个都在查找与查询参数匹配的节点。一个查找匹配online = yes的节点,另一个查找匹配offline = no的节点。请注意,代码实际上正在监视所有用户,但忽略了不在当前用户基地中的用户。

另一种方法是在addedQuery闭包中为每个属于此基地的用户/online节点添加单独的观察者,并在用户离开基地时在removeQuery中删除观察者。这个部分留给你来完成。

希望这个方案有助于减少数据传输的需求。

英文:

It seems line you are moving a lot of data around within the database. That can get expensive but also consumes a lot of bandwidth. In other words, with the current code, if a users status changes from online to offline, your code is currently removing all of the user data from one node and re-writing it to another when all that's really needed is to toggle an online flag from yes to no.

I present another option that may help in the long run and while it's not troubleshooting your existing code, it may be a better option.

The idea here is to keep the user data in one place and simply change the child nodes to reflect a different status; a different base, online/offline etc.

To do that, that if a property (child node) falls within the criteria of a query, you'll be notified. If it falls out of the criteria you'll be notified.

Here's what a proposed user node would look like. Note there are no offline or online nodes, just the users node

users
uid_0 //a users uid
base: "FRA"
name: "Frank"
online: "no"
uid_1
base: "ENG"
name: "Henry"
online: "yes"
uid_0 
base: "FRA"
name: "Leroy"
online: "yes"

From this you know that Frank is stationed in France but not online, Henry is in England and online and Leroy is also in France and online.

Here's my users class and an array to store them in

class UserAndBaseClass {
var uid = ""
var name = ""
var base = ""
var online = ""
init(withSnap: DataSnapshot) {
self.uid = withSnap.key
self.name = withSnap.childSnapshot(forPath: "name").value as? String ?? "No Name"
self.base = withSnap.childSnapshot(forPath: "base").value as? String ?? "No Base"
self.online = withSnap.childSnapshot(forPath: "online").value as? String ?? "Offline"
}
}
var usersArray = [UserAndBaseClass]()

In the first section of code, addedQuery, queries all of the users that belong to the current users base, FRA and stores them in an array. This leaves an observer on the users node so if any users base becomes FRA, it will then fall within that query's parameters and is added to the query. (hence firing the .childAdded event)

The second section, removedQuery, establishes a query on all users that match the query and the event is fired if the base becomes something other than FRA - e.g. the child is removed from the query parameters and the .childRemoved event fires.

Note we are not using .childChanged at all since the first two queries cover it.

func observeUserBases() {
let currentUserBase = "FRA"
//get everyone in the current users base, FRA. This also fires if a user changes to this base
let usersRef = self.ref.child("users")
let addedQuery = usersRef.queryOrdered(byChild: "base").queryEqual(toValue: currentUserBase)
addedQuery.observe(.childAdded, with: { snapshot in
let user = UserAndBaseClass(withSnap: snapshot)
self.usersArray.append(user)
print("\(user.name) has been added to your base")
})
//this will catch any users that were removed as well as users who left your base
let removedQuery = usersRef.queryOrdered(byChild: "base").queryEqual(toValue: "FRA")
removedQuery.observe(.childRemoved, with: { snapshot in
let keyToRemove = snapshot.key
if let index = self.usersArray.firstIndex(where: { $0.uid == keyToRemove } ) {
let name = self.usersArray[index].name
print("\(name) has left your base")
self.usersArray.remove(at: index)
}
})
let onlineQuery = usersRef.queryOrdered(byChild: "online").queryEqual(toValue: "yes")
onlineQuery.observe(.childAdded, with: { snapshot in
let keyOfChanged = snapshot.key
let base = snapshot.childSnapshot(forPath: "base").value as? String ?? "No Base"
if base == currentUserBase {
if let index = self.usersArray.firstIndex(where: { $0.uid == keyOfChanged } ) {
let name = self.usersArray[index].name
print("\(name) is now online")
self.usersArray[index].online = "yes"
}
}
})
let offlineQuery = usersRef.queryOrdered(byChild: "online").queryEqual(toValue: "no")
offlineQuery.observe(.childAdded, with: { snapshot in
let keyOfChanged = snapshot.key
let base = snapshot.childSnapshot(forPath: "base").value as? String ?? "No Base"
if base == currentUserBase {
if let index = self.usersArray.firstIndex(where: { $0.uid == keyOfChanged } ) {
let name = self.usersArray[index].name
print("\(name) has gone offline")
self.usersArray[index].online = "no"
}
}
})
}

The last two sections, online and offline query, are structured a little different; each is looking for nodes that match the query parameters. One is looking for nodes that match online = yes, the offline one matches nodes that match offline = no. Noting that the code is actually watching ALL users but ignoring users that are not in the current users base.

An alternative to this is to add individual observers to each users/online node that's part of this base. You would do that in the addedQuery closure and add an observer to each users node as it's added, and then in the removeQuery, remove the observer as the user leaves the base. I will leave that to an exercise.

Hope this helps by presenting an alternative to moving all of that data around.

huangapple
  • 本文由 发表于 2020年1月6日 20:12:58
  • 转载请务必保留本文链接:https://go.coder-hub.com/59611908.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定