Firebase数据后无法返回行数及TableView用户类型适配报错问询
解决你的Firebase与TableView问题
问题2:「Unexpected non-void return value in void function」错误
这个报错本质很明确:你在一个没有返回值的函数(void function)里写了return语句返回值。通常这个情况出现在两种场景:
- 你把判断用户类型的return逻辑写在了Firebase的异步回调闭包里(比如
getDocuments的completion闭包)——这个闭包本身是void类型,不能返回任何值; - 你误把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。
正确的解决步骤
- 先定义两个数组分别存储不同用户类型的数据:
// 根据你的数据模型替换YourDataType var adminExclusiveData: [YourDataType] = [] var regularUserdata: [YourDataType] = [] var typeOfUser: String = "" // 假设你已经从登录逻辑里拿到了用户类型
- 在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() } } }
- 最后在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
相关产品推荐
相关产品推荐

