简体   繁体   中英

Duplicates child node when setting a value Firebase

I've been trying to fix this for the last few days but keep ending up with the same result. When a user clicks to add a friend, it adds the friend's id as a node under "friends" (as expected); however, when I go to try and update or set a value for that id, it adds the id again with the value instead of just adding the value to the existing child. How do I make this so that it adds it without adding a whole other child?

在此处输入图像描述

Here's the code that adds the friend:

 func saveFriend(selectedFriend: FUser) {

    if friendId.contains(selectedFriend.objectId as String) {

        return
    }

    //get current friends
    var currentFriends = FUser.currentUser()!.friends

    currentFriends.append(selectedFriend.objectId)

    let newDate = dateFormatter().string(from: Date())
    let secondsDate: Int = Int(Date().timeIntervalSince1970)


    updateUser(withValues: [kFRIEND : currentFriends, kUPDATEDAT : newDate, kSECONDSDATEUPDATED : secondsDate]) { (success) in

        self.loadFriends()
        NotificationCenter.default.post(name: .addedFriend, object: nil)

    }


}

And this is the code to add the value (with the updateChildValues commented out that I also tried and had the same result):

func increaseFriendshipValue(increase: Int) {
    let friend = withUsers.first!.objectId
    let friendValueRef = firebase.child(kUSER).child(FUser.currentId()).child(kFRIEND).child(friend)

   // friendValueRef.updateChildValues([friend: +increase])

    friendValueRef.setValue(increase)


}

Edit: This is what I currently have in my Friends view where I load the friends from how they were added to an array (without the value):

  @objc func loadFriends() {
    cleanup()

    let friendIds = FUser.currentUser()!.friends

    if friendIds.count > 0 {

        for friendId in friendIds {

            firebase.child(kUSER).queryOrdered(byChild: kOBJECTID).queryEqual(toValue: friendId).observeSingleEvent(of: .value) { (snapshot) in

                if snapshot.exists() {
                    let userDictionary = ((snapshot.value as! NSDictionary).allValues as Array).first

                    let fuser = FUser.init(_dictionary: userDictionary as! NSDictionary)

                    self.friends.append(fuser)
                    self.friendId.append(fuser.objectId)
                    self.friends.sort(by: {$0.username < $1.username})
                }
                self.tableView.reloadData()

            }

        }

    } else {
        ProgressHUD.showError("You currently have no friends saved. Please unlock some")
    }

}

You're writing the data in two different formats.

First in saveFriend , you're writing in this format:

"friends": {
  "0": "uidOfTheUser",
  "1": "uidOfAnotherUser"
}

Then in increaseFriendshipValue , you're updating it as:

"friends": {
  "uidOfTheUser": 1,
  "uidOfAnotherUser": 0
}

Since you seem to want to actually keep a count per user, I'm going to assume the latter is the correct structure. This means you need to write the user in that format in saveFriend too.

The problem seems to be in:

var currentFriends = FUser.currentUser()!.friends

currentFriends.append(selectedFriend.objectId)

Here, you're adding selectedFriend.objectId to an array, which means that Swift generates a new array element: the 0 and 1 in the first JSON snippet above.

What you'll actually want to do is write straight to the database, similar to what you do in increaseFriendshipValue . Assuming the initial count is 0 , that'd be something like:

let friendsRef = firebase.child(kUSER).child(FUser.currentId()).child(kFRIEND)

let newFriendRef = child(selectedFriend.objectId)

newFriendRef.setValue(0)

A few things to note:

  1. You really should be using a transaction to increase the friend value, as otherwise writes from multiple users may overwrite each other's results.
  2. Right now saveFriend seems to have a significant risk of overwriting an existing value for a friend. You're probably checking if the users are already befriended somewhere in the code, but here too you'll want to use a transaction.
  3. If you're using a transaction in both cases, you might want to merge the code for create the "friend" node and the code for updating it into one function, as they're going to look very similar.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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