Firebase点赞功能实现异常:点击点赞按钮后出现Optional值为nil问题
解决Firebase点赞功能中的Optional nil问题
我帮你梳理下代码里可能触发nil崩溃的点,以及优化点赞逻辑的方法:
1. 强制解包currentUser是高危操作
你代码里用了Auth.auth().currentUser!.uid,如果用户未登录,currentUser就是nil,强制解包会直接崩溃。先做安全检查:
guard let currentUserUID = Auth.auth().currentUser?.uid else { print("用户还没登录哦") self.like.isEnabled = true return }
2. postID为空也会导致问题
如果首页的postID没正确赋值,self.postID就是nil,传给Firebase的child节点会出错。同样加个安全校验:
guard let postID = self.postID else { print("postID是空的,检查下首页的赋值逻辑") self.like.isEnabled = true return }
3. 优化点赞数据存储的逻辑
你原本用childByAutoId()生成的key来存点赞用户UID,其实更合理的是用点赞用户的UID作为key——这样既能避免同一个用户重复点赞,还能让数据结构更直观。修改后的完整点击事件代码如下:
@IBAction func likePressed(_ sender: Any) { self.like.isEnabled = false // 安全获取当前用户UID guard let currentUserUID = Auth.auth().currentUser?.uid else { print("用户未登录,无法点赞") self.like.isEnabled = true return } // 安全获取被点赞用户的postID guard let postID = self.postID else { print("postID为空,请检查首页赋值") self.like.isEnabled = true return } let ref = Database.database().reference() // 先检查用户是否已经点过赞 ref.child("people").child(postID).child("peopleWhoLike").child(currentUserUID).observeSingleEvent(of: .value) { snapshot in if snapshot.exists() { // 已经点过赞,可以加取消点赞的逻辑(可选) print("你已经点过赞啦") self.like.isEnabled = true } else { // 存入点赞记录:用当前用户UID作为key,值设为true即可 let updateLikes: [String: Any] = ["peopleWhoLike/\(currentUserUID)" : true] ref.child("people").child(postID).updateChildValues(updateLikes) { error, _ in if let error = error { print("点赞失败:\(error.localizedDescription)") self.like.isEnabled = true return } // 更新点赞数并同步到UI ref.child("people").child(postID).child("peopleWhoLike").observeSingleEvent(of: .value) { snap in let likeCount = snap.childrenCount self.likeLabel.text = "\(likeCount) Likes" ref.child("people").child(postID).updateChildValues(["likes": likeCount]) self.like.isEnabled = true } } } } ref.removeAllObservers() }
4. 修正首页postID的赋值代码
你首页的代码override func Table View: cell.postID = self.people[indexPath.row].postID语法不对,应该在cellForRowAt方法里正确赋值:
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: "你的CellID", for: indexPath) as! 你的自定义Cell类 let targetPerson = self.people[indexPath.row] cell.postID = targetPerson.postID // 确保targetPerson有postID属性且不为空 // 其他UI赋值逻辑... return cell }
修改后,你的Firebase数据库会变成预期的结构:
"people" : { "9RYUttVhCzXKs6H1XnZ63TZ8Dun2" : { "Coordinates" : { "latitude" : 15.78583, "longitude" : -4.406417 }, "Education" : "CS", "PhotoPosts" : "https://firebasestorage.googleapis.com/v0/b/daylike-2f938.appspot.com/o/images%2FPhotoPosts?alt=media&token=ac9e574f-b55f-4bf0-b75b-79b877a86480", "caption" : 1563439869418, "users" : "nane19@aol.com", "peopleWhoLike": { "点赞用户的UID": true }, "likes": 1 } }
这样既解决了Optional nil的崩溃问题,又优化了点赞逻辑,避免重复点赞,数据结构也更清晰。
内容的提问来源于stack exchange,提问作者noname87f
相关产品推荐
相关产品推荐

