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

Firebase Swift中如何获取指定UID用户数据及当前用户好友数据?

我来帮你解决这两个Firebase Swift开发中的问题,分两部分详细讲解:

一、获取特定UID用户的数据

不管你用的是Firebase Realtime Database还是Firestore,核心逻辑都是通过用户UID直接定位到对应的数据源节点/文档,然后读取数据。

1. 针对Realtime Database的实现

假设你的用户数据存在users节点下,每个用户的UID作为节点key,结构如下:

users
  |- {userUID1}
      |- name: "张三"
      |- email: "zhangsan@example.com"
  |- {userUID2}
      |- name: "李四"
      |- email: "lisi@example.com"

代码示例:

import FirebaseDatabase

// 替换成你要查询的目标用户UID
let targetUserUID = "your-target-user-uid"
let userRef = Database.database().reference().child("users").child(targetUserUID)

// 单次读取数据(如果需要实时监听变化,把observeSingleEvent改成observe)
userRef.observeSingleEvent(of: .value) { snapshot in
    guard let userData = snapshot.value as? [String: Any] else {
        print("未找到该用户的数据")
        return
    }
    // 解析数据,这里可以转成自定义的User模型类/结构体
    let userName = userData["name"] as? String ?? "匿名用户"
    let userEmail = userData["email"] as? String ?? ""
    print("获取到用户信息:\(userName) - \(userEmail)")
}

2. 针对Firestore的实现

如果用Firestore,用户数据存在users集合中,每个文档ID就是用户UID,代码逻辑类似:

import FirebaseFirestore

let targetUserUID = "your-target-user-uid"
let db = Firestore.firestore()

db.collection("users").document(targetUserUID).getDocument { document, error in
    if let error = error {
        print("获取用户数据失败:\(error.localizedDescription)")
        return
    }
    guard let document = document, document.exists else {
        print("该用户文档不存在")
        return
    }
    // 解析数据
    let userData = document.data()
    let userName = userData?["name"] as? String ?? "匿名用户"
    let userEmail = userData?["email"] as? String ?? ""
    print("获取到用户信息:\(userName) - \(userEmail)")
}
二、获取当前用户的联系人(friends)数据并适配TableView

虽然你提到的存储结构图片没法看到,但我会基于最常见的两种存储场景来讲解,你可以根据自己的实际结构调整。

场景1:Realtime Database中friends节点存储关联UID(键值对形式)

假设结构如下(当前用户的friends节点下,每个key是联系人的UID,值为true标记关联):

users
  |- {currentUserUID}
      |- friends
          |- {friendUID1}: true
          |- {friendUID2}: true

实现步骤:

  1. 确认用户已登录,获取当前用户UID
  2. 读取当前用户的friends节点,拿到所有联系人UID
  3. 批量获取每个联系人的详细数据
  4. 存储到数组中,刷新TableView

代码示例(包含TableView适配):

import FirebaseAuth
import FirebaseDatabase

// 自定义用户模型,方便TableView展示数据
struct Friend {
    let uid: String
    let name: String
    let email: String
}

class FriendsListVC: UIViewController, UITableViewDataSource {
    @IBOutlet weak var friendsTableView: UITableView!
    
    private var friendsArray: [Friend] = []
    
    override func viewDidLoad() {
        super.viewDidLoad()
        friendsTableView.dataSource = self
        // 注册TableViewCell(如果是storyboard中设置了identifier可以跳过)
        friendsTableView.register(UITableViewCell.self, forCellReuseIdentifier: "FriendCell")
        fetchFriendsData()
    }
    
    private func fetchFriendsData() {
        guard let currentUID = Auth.auth().currentUser?.uid else {
            print("用户未登录,请先登录")
            return
        }
        
        // 读取当前用户的联系人UID列表
        let friendsRef = Database.database().reference().child("users").child(currentUID).child("friends")
        friendsRef.observeSingleEvent(of: .value) { [weak self] snapshot in
            guard let friendUIDs = snapshot.value as? [String: Bool] else {
                print("当前用户暂无联系人")
                return
            }
            
            self?.friendsArray.removeAll()
            let dispatchGroup = DispatchGroup() // 用于批量处理请求,避免多次刷新TableView
            
            for (friendUID, _) in friendUIDs {
                dispatchGroup.enter()
                // 获取单个联系人的详细数据
                let userRef = Database.database().reference().child("users").child(friendUID)
                userRef.observeSingleEvent(of: .value) { snapshot in
                    defer { dispatchGroup.leave() } // 不管成功失败都标记任务完成
                    
                    guard let userData = snapshot.value as? [String: Any],
                          let name = userData["name"] as? String,
                          let email = userData["email"] as? String else {
                        return
                    }
                    
                    let friend = Friend(uid: friendUID, name: name, email: email)
                    self?.friendsArray.append(friend)
                }
            }
            
            // 所有请求完成后,在主线程刷新TableView
            dispatchGroup.notify(queue: .main) {
                self?.friendsTableView.reloadData()
            }
        }
    }
    
    // MARK: - UITableView DataSource
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return friendsArray.count
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "FriendCell", for: indexPath)
        let friend = friendsArray[indexPath.row]
        cell.textLabel?.text = friend.name
        cell.detailTextLabel?.text = friend.email
        return cell
    }
}

场景2:Firestore中friends字段是UID数组

假设Firestore的users集合中,当前用户文档有一个friends数组字段,存储所有联系人的UID:

users/{currentUID}
  |- name: "当前用户名称"
  |- friends: ["friendUID1", "friendUID2"]

实现步骤:

  1. 获取当前用户文档,读取friends数组
  2. 批量查询这些UID对应的用户文档
  3. 解析数据到数组,刷新TableView

代码示例:

import FirebaseAuth
import FirebaseFirestore

struct Friend {
    let uid: String
    let name: String
    let email: String
}

class FriendsListVC: UIViewController, UITableViewDataSource {
    @IBOutlet weak var friendsTableView: UITableView!
    private var friendsArray: [Friend] = []
    private let db = Firestore.firestore()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        friendsTableView.dataSource = self
        friendsTableView.register(UITableViewCell.self, forCellReuseIdentifier: "FriendCell")
        fetchFriendsData()
    }
    
    private func fetchFriendsData() {
        guard let currentUID = Auth.auth().currentUser?.uid else {
            print("用户未登录,请先登录")
            return
        }
        
        // 获取当前用户的联系人UID数组
        db.collection("users").document(currentUID).getDocument { [weak self] document, error in
            if let error = error {
                print("获取联系人列表失败:\(error.localizedDescription)")
                return
            }
            guard let document = document, document.exists,
                  let friendUIDs = document["friends"] as? [String] else {
                print("当前用户暂无联系人")
                return
            }
            
            // 批量查询所有联系人的文档
            self?.db.collection("users")
                .whereField(FieldPath.documentID(), in: friendUIDs)
                .getDocuments { querySnapshot, error in
                    if let error = error {
                        print("获取联系人数据失败:\(error.localizedDescription)")
                        return
                    }
                    guard let documents = querySnapshot?.documents else {
                        print("未找到联系人数据")
                        return
                    }
                    
                    // 解析数据到数组
                    self?.friendsArray = documents.compactMap { doc in
                        guard let name = doc["name"] as? String,
                              let email = doc["email"] as? String else {
                            return nil
                        }
                        return Friend(uid: doc.documentID, name: name, email: email)
                    }
                    
                    // 主线程刷新TableView
                    DispatchQueue.main.async {
                        self?.friendsTableView.reloadData()
                    }
                }
        }
    }
    
    // MARK: - UITableView DataSource
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return friendsArray.count
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "FriendCell", for: indexPath)
        let friend = friendsArray[indexPath.row]
        cell.textLabel?.text = friend.name
        cell.detailTextLabel?.text = friend.email
        return cell
    }
}

补充提示

如果你的friends存储结构和上面两种都不同,比如是嵌套对象或者其他形式,可以把具体的数据库结构(JSON或截图描述)提供出来,我可以帮你调整查询逻辑。另外,一定要确保Firebase的安全规则设置正确,允许用户读取自己的friends数据,以及其他用户的公开信息(比如name、email)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 09:07:33