Synchronized Array (for likes/followers) Best Practice [Firebase Swift]

三世轮回 提交于 2019-12-18 13:39:17

问题


I'm trying to create a basic following algorithm using Swift and Firebase. My current implementation is the following:

static func follow(user: FIRUser, userToFollow: FIRUser) {
    database.child("users").child(user.uid).observeSingleEventOfType(.Value, withBlock: { (snapshot) in
        var dbFollowing: NSMutableArray! = snapshot.value!["Following"] as! NSMutableArray!
        dbFollowing?.addObject(userToFollow.uid)
        self.database.child("users/"+(user.uid)+"/").updateChildValues(["Following":dbFollowing!])
        //add user uid to userToFollows followers array in similar way
    }) { (error) in
        print("follow - data could not be retrieved - EXCEPTION: " + error.localizedDescription)
    }
}

This retrieves the array of from Firebase node Following, adds the uid of userToFollow, and posts the new array to node Following. This has a few problems:

  1. It is not synchronized so if it is called at the same time on two devices one array will overwrite the other and followers will not be saved.
  2. If there are no followers it cannot deal with a nil array, the program will crash (not the main concern, I can probably address with optionals).

I was wondering what the best practice might be to created a synchronized array of uid/tokens for user followers or post likes. I found the following links, but none seem to directly address my problem and seem to carry other problems with it. I figured it would be wise to ask the community with experience instead of Frankensteining a bunch of solutions together.

https://firebase.googleblog.com/2014/05/handling-synchronized-arrays-with-real.html https://firebase.google.com/docs/database/ios/save-data (the save data as transaction section)

Thanks for your help!


回答1:


Thanks to Frank, I figured out a solution using runTransactionBlock. Here it is:

static func follow(user: FIRUser, userToFollow: FIRUser) {
    self.database.child("users/"+(user.uid)+"/Following").runTransactionBlock({ (currentData: FIRMutableData!) -> FIRTransactionResult in
        var value = currentData?.value as? Array<String>
        if (value == nil) {
            value = [userToFollow.uid]
        } else {
            if !(value!.contains(userToFollow.uid)) {
                value!.append(userToFollow.uid)
            }
        }
        currentData.value = value!
        return FIRTransactionResult.successWithValue(currentData)
        }) { (error, committed, snapshot) in
            if let error = error {
            print("follow - update following transaction - EXCEPTION: " + error.localizedDescription)
        }
    }
}

This adds the uid of userToFollow to the array Following of user. It can handle nil values and will initialize accordingly, as well as will disregard the request if the user is already following the uid of userToFollow. Let me know if you have any questions!

Some useful links:

  1. The comments of firebase runTransactionBlock
  2. The answer to Upvote/Downvote system within Swift via Firebase
  3. The second link I posted above


来源:https://stackoverflow.com/questions/38999383/synchronized-array-for-likes-followers-best-practice-firebase-swift

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!