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

Firebase数据后无法返回行数及TableView用户类型适配报错问询

解决你的Firebase与TableView问题

问题2:「Unexpected non-void return value in void function」错误

这个报错本质很明确:你在一个没有返回值的函数(void function)里写了return语句返回值。通常这个情况出现在两种场景:

  1. 你把判断用户类型的return逻辑写在了Firebase的异步回调闭包里(比如getDocuments的completion闭包)——这个闭包本身是void类型,不能返回任何值;
  2. 你误把tableView的数据源方法(比如numberOfRowsInSection)的返回值类型写错了,写成了void。

正确的解决方式

确保你的判断逻辑写在正确的数据源方法里,比如numberOfRowsInSection本身就是需要返回Int的方法,在这里根据用户类型返回对应数据的行数就没问题:

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    // 根据用户类型返回对应数据的行数
    if typeOfUser == "admin" {
        return adminData.count // admin专属数据数组的长度
    } else {
        return regularUserData.count // 普通用户数据数组的长度
    }
}

如果之前你是在Firebase的回调里写return,那绝对不行——回调是异步执行的,而且本身不允许返回值,正确的做法是在回调里把数据存到数组,然后刷新tableView,让数据源方法自己去返回行数。


问题1:获取Firebase数据后无法返回行数

这个问题的核心是Firebase的数据获取是异步操作——你调用getDocuments之后,主线程不会等数据返回就会继续执行后面的代码,所以如果一开始你直接去返回数组的count,数组还是空的,自然返回0。

正确的解决步骤

  1. 先定义两个数组分别存储不同用户类型的数据:
// 根据你的数据模型替换YourDataType
var adminExclusiveData: [YourDataType] = []
var regularUserdata: [YourDataType] = []
var typeOfUser: String = "" // 假设你已经从登录逻辑里拿到了用户类型
  1. 在Firebase获取数据的回调里,把解析好的数据赋值给对应数组,然后回到主线程刷新tableView:
func fetchFirebaseData() {
    let db = Firestore.firestore()
    let targetCollection = typeOfUser == "admin" ? "admin_collection" : "regular_collection"
    
    db.collection(targetCollection).getDocuments { snapshot, error in
        if let error = error {
            print("数据获取失败:\(error.localizedDescription)")
            return
        }
        
        guard let docs = snapshot?.documents else { return }
        // 解析数据到对应数组
        if self.typeOfUser == "admin" {
            self.adminExclusiveData = docs.compactMap { doc in
                // 这里替换成你的数据模型解析逻辑
                try? doc.data(as: YourDataType.self)
            }
        } else {
            self.regularUserdata = docs.compactMap { doc in
                try? doc.data(as: YourDataType.self)
            }
        }
        
        // 必须回到主线程刷新表格,因为UI操作只能在主线程执行
        DispatchQueue.main.async {
            self.tableView.reloadData()
        }
    }
}
  1. 最后在tableView的数据源方法里,根据用户类型返回对应数组的count:
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return typeOfUser == "admin" ? adminExclusiveData.count : regularUserdata.count
}

// 同理,cell的配置也要对应不同的数组
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "YourCellID", for: indexPath) as! YourCellClass
    let currentData = typeOfUser == "admin" ? adminExclusiveData[indexPath.row] : regularUserdata[indexPath.row]
    
    // 配置cell的内容,比如:
    cell.titleLabel.text = currentData.title
    cell.contentLabel.text = currentData.content
    
    return cell
}

这样等Firebase数据异步返回后,数组被赋值,tableView刷新,数据源方法就会返回正确的行数了。


内容的提问来源于stack exchange,提问作者D. Finna

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 09:03:16