You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Swift中Firebase实时数据库更新好友数据并刷新TableView问题

我来帮你解决这个Firebase实时更新的问题!

核心问题诊断

你自己已经点出了关键:watchForChangesInMyFriends函数里找到好友索引后,只是把原对象重新赋值给数组,完全没用到Firebase返回的最新snapshot去生成新的FriendClass实例——数组里的元素还是旧数据,TableView刷新当然看不出变化。

修正后的关键代码

直接修改watchForChangesInMyFriends函数,用新snapshot创建更新后的好友对象,同时别忘了UI操作必须在主线程执行:

func watchForChangesInMyFriends() {
    let usersRef = self.ref.child("profiles")
    usersRef.observe(.childChanged, with: { snapshot in
        let key = snapshot.key
        if let friendIndex = self.myFriendsDataSource.firstIndex(where: { $0.uid == key} ) {
            // 用最新的snapshot生成更新后的FriendClass实例
            let updatedFriend = FriendClass(withSnapshot: snapshot)
            print("found user \(updatedFriend.batteryStatus), updating")
            self.myFriendsDataSource[friendIndex] = updatedFriend
            
            // Firebase回调在后台线程,必须切回主线程刷新UI
            DispatchQueue.main.async {
                self.tableView.reloadData()
            }
        }
    })
}

额外优化:避免重复监听&主线程刷新

还有两个小细节能帮你避免潜在bug:

  1. 不要重复添加监听:你现在在loadFriend里每加载一个好友就调用一次watchForChangesInMyFriends,这会导致Firebase重复注册监听事件。应该把监听的调用移到所有好友加载完成后,只执行一次:
func loadUsersFriends() {
    let uid = "zzV6DQSXUyUkPHgENDbZ9EjXVBj2"
    let myFriendsRef = self.ref.child("userFriends").child(uid)
    myFriendsRef.observeSingleEvent(of: .value, with: { snapshot in
        let uidArray = snapshot.children.allObjects as! [DataSnapshot]
        for friendsUid in uidArray {
            self.loadFriend(withUid: friendsUid.key)
            print(friendsUid)
        }
        // 所有好友加载完成后,再注册实时监听
        self.watchForChangesInMyFriends()
    })
}
  1. 所有UI更新都要在主线程:loadFriend里的tableView.reloadData()同样需要包裹在DispatchQueue.main.async里,因为Firebase的observeSingleEvent回调也是在后台线程执行的:
func loadFriend(withUid: String) {
    let thisUserRef = self.ref.child("profiles").child(withUid)
    thisUserRef.observeSingleEvent(of: .value, with: { snapshot in
        let aFriend = FriendClass(withSnapshot: snapshot)
        self.myFriendsDataSource.append(aFriend)
        print(self.myFriendsDataSource)
        
        DispatchQueue.main.async {
            self.tableView.reloadData()
        }
        // 这里不要再调用watchForChangesInMyFriends了!
    })
}

这样修改后,当Firebase数据库中的好友资料(比如位置、电量)更新时,你的数据源数组会立刻拿到最新的对象,TableView也能正确刷新显示最新内容啦。

内容的提问来源于stack exchange,提问作者Newbie

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 08:28:44