If you have a firebase snapshot with a filter applied to the current user’s child, how can one do that for all users in the database?

Viewed 112

If you have a firebase snapshot that you are filtering for the current user, how do you do that for all users in the database?

 Path: (people.child(uid).child(peopleWhoLike2)  

It works for the current user, but I want it for all users. Probably something like for peopleArray in snapshot.children.allObjects as! [DataSnapshot] { needs to be used. Below is code for current

        let thisUserRef1 = Database.database().reference().child("people").child(uid)
                 let myPeopleRef1 = thisUserRef1.child("peopleWhoLike2")
        myPeopleRef1.observeSingleEvent(of:DataEventType.value, with: { snapshot in
        print("klk")
         
         let peopleArray = snapshot.children.allObjects as! [DataSnapshot]
            let filteredResults = peopleArray.filter { person in
                let personUid = person.value as! Int
                let coordSnap12 = personUid
                
            
            print("kjk", coordSnap12 )
                       let date = Date(timeIntervalSince1970: TimeInterval(coordSnap12)/1000.0)
                       //let secondsInDay = 86400
                  
                return Calendar.current.isDateInToday(date)

                }
            
            
            print(filteredResults, "ppp")
            let countb = filteredResults.compactMap({$0}).count
            print(countb, "ccc")

JSON DB Structure

"people" : {
"1ZWT7FAE2qThNQfBj7tbMO7BnMo1" : {
  "Coordinates" : {
    "latitude" : 50.054738,
    "longitude" : 8.226809826085624
  "peopleWhoLike2" : {
    "1vLVFwrXrHUoakmDrnQKwbv08Yj1" : 1581548952597,
    "F9NX0UCG4fVHCKFk2VZ1NZKsLro2" : 1586210112155,
    "IrrBgFY9C1ekMmHUkQRzc5LhbDu1" : 1581547417432,
    
1 Answers

Firebase Realtime Database doesn't have a direct way to get the count of number of children in a node without reading in that nodes data. So there are two methods.

  1. Observe the node, iterating over the children with .childAdded to get a count. Or, along those same lines load in all of the children with .value - to which you can get a count of the snapshots children. The downside there is it could be a LOT of data so with larger datasets, or unknown amount of children this is discouraged. It's also very read heavy obviously as if you have 1000 users, it's a lot of data to parse through.

  2. Keep a separate node of the child count (this is the winner!)

The additional node would look like this

like_me_counts
   "1ZWT7FAE2qThNQfBj7tbMO7BnMo1": 3
   "another user id": 20
   "yet another user id": 12

So as a user has another person like them, add the 'liker' to the "peopleWhoLike2" node as shown in your question, and then increment that users matching node within the like_me_counts node.

In this case if another person like user 1ZWT7... read that in from the like_me_counts node to get the value of 3, add one and then write out 4. If a user unlikes them, read it in, subtract 1 and write out the new value.

You can wrap all of that into a transaction so it either all succeeds or all fails.

EDIT

I would even go so far to say that it may be best to break out the people who like you into it's own node

like_me
   uid_0
      user_10: true
      user_11: true
   uid_1
      user_39: true
   uid_2
      user_46: true

What that structure, each user would add a child added observer to their like_me node, and when someone likes them... say user_52 likes user_2

   uid_2
      user_46: true
      user_52: true

then uid_2 will receive that notification and can handle it. Obviously, I am just using true as a placeholder but there could be other info such as a time stamp or even child nodes that can be used for filtering (for todays likes only for example)

  uid_2
     user_46: 20200624
     user_52: 20200629
     
Related