FirebaseTableViewDataSource 在用户注销和登录时崩溃
FirebaseTableViewDataSource crashes on user signout and signin
我的应用有一个 UITableViewController,它使用 FirebaseTableViewDataSource(来自 FirebaseUI)。 table 正确显示用户的 post 书签,但是当我注销该用户并登录另一个用户时,应用程序崩溃并显示以下消息:
* Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Invalid update: invalid number of rows in section 0. The number of rows contained in an existing section after the update (1) must be equal to the number of rows contained in that section before the update (2), plus or minus the number of rows inserted or deleted from that section (1 inserted, 0 deleted) and plus or minus the number of rows moved into or out of that section (0 moved in, 0 moved out).'*
我怀疑问题与 FirebaseUI 如何更新 tableView 的内容有关。过去 4 天我一直在调试它;搜索了 SO 问题;阅读相关文档,但 none 提到了这个独特的问题。任何帮助将不胜感激。
详情(抱歉其实有点长)
这是我的数据库结构:
|
+-posts
| |
| +-$postid
| |
| +-/* properties of a post: title, text, etc */
|
+-users
|
+-$userid
|
+-bookmarks
|
+-post1: true
|
+-post2: true
我正在使用 FirebaseUI 通过将 users/$userid/bookmarks
引用作为查询传递给 FirebaseTableViewDataSource 来向用户显示 his/her 书签。然后对于每个键,我观察 posts/$postid
上的单个值事件以检索 post 详细信息...下面的代码:
self.authStateListenerHandle = FIRAuth.auth()?.addStateDidChangeListener { auth, user in
guard let user = user else {
return
}
self.query = FIRDatabase.database().reference().child("users").child(user.uid).child("bookmarks")
self.tableViewDataSource = FirebaseTableViewDataSource(query: self.query!, view: self.tableView, populateCell: { (tableView, indexPath, snapshot) -> UITableViewCell in
if snapshot.exists() {
let postRef = FIRDatabase.database().reference().child("posts").child(snapshot.key)
let cell = tableView.dequeueReusableCell(withIdentifier: BookmarksVC.reuseIdentifier, for: indexPath) as! MiniTableCell
postRef.observeSingleEvent(of: .value, with: { (snapshot) in
if snapshot.exists() {
let post = Event(snapshot: snapshot)!
let postVM = EventViewModel(post: post)
cell.populateCellWithEvent(postVM)
cell.delegate = self
}
})
return cell
}
else {
return UITableViewCell()
}
})
self.tableView.dataSource = self.tableViewDataSource
}
我把上面的代码放在viewDidAppear里,然后像这样去掉viewWillDisappear里的authStateListenerHandle
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
if let handle = self.authStateListenerHandle {
FIRAuth.auth()?.removeStateDidChangeListener(handle)
}
}
几乎一切正常,除了当我查看用户的书签,然后注销并重新登录时,应用程序崩溃并显示消息
* Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Invalid update: invalid number of rows in section 0. The number of rows contained in an existing section after the update (1) must be equal to the number of rows contained in that section before the update (2), plus or minus the number of rows inserted or deleted from that section (1 inserted, 0 deleted) and plus or minus the number of rows moved into or out of that section (0 moved in, 0 moved out).'
*
在viewWillDisappear
中设置self.tableViewDataSource = nil
。所以,你没有不正确地更新 dataSource
。
我的应用有一个 UITableViewController,它使用 FirebaseTableViewDataSource(来自 FirebaseUI)。 table 正确显示用户的 post 书签,但是当我注销该用户并登录另一个用户时,应用程序崩溃并显示以下消息:
* Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Invalid update: invalid number of rows in section 0. The number of rows contained in an existing section after the update (1) must be equal to the number of rows contained in that section before the update (2), plus or minus the number of rows inserted or deleted from that section (1 inserted, 0 deleted) and plus or minus the number of rows moved into or out of that section (0 moved in, 0 moved out).'*
我怀疑问题与 FirebaseUI 如何更新 tableView 的内容有关。过去 4 天我一直在调试它;搜索了 SO 问题;阅读相关文档,但 none 提到了这个独特的问题。任何帮助将不胜感激。
详情(抱歉其实有点长)
这是我的数据库结构:
|
+-posts
| |
| +-$postid
| |
| +-/* properties of a post: title, text, etc */
|
+-users
|
+-$userid
|
+-bookmarks
|
+-post1: true
|
+-post2: true
我正在使用 FirebaseUI 通过将 users/$userid/bookmarks
引用作为查询传递给 FirebaseTableViewDataSource 来向用户显示 his/her 书签。然后对于每个键,我观察 posts/$postid
上的单个值事件以检索 post 详细信息...下面的代码:
self.authStateListenerHandle = FIRAuth.auth()?.addStateDidChangeListener { auth, user in
guard let user = user else {
return
}
self.query = FIRDatabase.database().reference().child("users").child(user.uid).child("bookmarks")
self.tableViewDataSource = FirebaseTableViewDataSource(query: self.query!, view: self.tableView, populateCell: { (tableView, indexPath, snapshot) -> UITableViewCell in
if snapshot.exists() {
let postRef = FIRDatabase.database().reference().child("posts").child(snapshot.key)
let cell = tableView.dequeueReusableCell(withIdentifier: BookmarksVC.reuseIdentifier, for: indexPath) as! MiniTableCell
postRef.observeSingleEvent(of: .value, with: { (snapshot) in
if snapshot.exists() {
let post = Event(snapshot: snapshot)!
let postVM = EventViewModel(post: post)
cell.populateCellWithEvent(postVM)
cell.delegate = self
}
})
return cell
}
else {
return UITableViewCell()
}
})
self.tableView.dataSource = self.tableViewDataSource
}
我把上面的代码放在viewDidAppear里,然后像这样去掉viewWillDisappear里的authStateListenerHandle
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
if let handle = self.authStateListenerHandle {
FIRAuth.auth()?.removeStateDidChangeListener(handle)
}
}
几乎一切正常,除了当我查看用户的书签,然后注销并重新登录时,应用程序崩溃并显示消息
* Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Invalid update: invalid number of rows in section 0. The number of rows contained in an existing section after the update (1) must be equal to the number of rows contained in that section before the update (2), plus or minus the number of rows inserted or deleted from that section (1 inserted, 0 deleted) and plus or minus the number of rows moved into or out of that section (0 moved in, 0 moved out).' *
在viewWillDisappear
中设置self.tableViewDataSource = nil
。所以,你没有不正确地更新 dataSource
。