FirebaseTableViewDataSource在用户注销和登录时崩溃 [英] FirebaseTableViewDataSource crashes on user signout and signin

查看:114
本文介绍了FirebaseTableViewDataSource在用户注销和登录时崩溃的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的应用程序有一个使用FirebaseTableViewDataSource(来自FirebaseUI)的UITableViewController。该表正确地显示了用户的添加书签的帖子,但是当我将该用户注销并登录另一个用户时,该应用程序崩溃并显示以下消息:

lockquote
*由于未捕获的异常'NSInternalInconsistencyException',原因:'无效的更新:在0节中的行数无效。更新(1)后现有节中包含的行数必须等于在更新之前包含在该部分中的行数(2),加上或减去从该部分插入或删除的行数(插入1个,删除0个)以及加上或减去移入或移出该部分的行数(0移入,0移出)。'*


我怀疑问题与FirebaseUI如何更新tableView的内容。我过去4天正在调试这个;搜索SO问题;阅读相关文档,但没有提到这个独特的问题。任何帮助将不胜感激。



详情(抱歉它实际上很长)

这是我的数据库结构:

  | 
+ -posts
| |
| + - $ postid
| |
| + - / *帖子的属性:标题,文本等* /
|
+ -users
|
+ - $ userid
|
+ -bookmarks
|
+ -post1:true
|
+ -post2:true

我正在使用FirebaseUI向用户显示他/她的书签通过将 users / $ userid / bookmarks ref作为查询传递给FirebaseTableViewDataSource。然后,对于每个键,我观察 posts / $ postid 上的单个值事件,以便检索帖子详细信息...

  self.authStateListenerHandle = FIRAuth.auth()?. addStateDidChangeListener {auth,用户在

guard let user = user else {


$ b 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

如果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
}
})

返回单元格
}
else {
return UITableViewCell()
}
})

self.tableView.dataSource = self.tableViewDataSource





$ b我把上面的代码放在viewDidAppear中,然后在viewWillDisappear中移除authStateListenerHandle就像这样

 重写func viewWillDisappear(_ animated:Bool){
super.viewWillDisappear(animated)
if let handle = self.authStateListenerHandle {
FIRAuth.auth()?. removeStateDidChangeListener(handle)
}
}



几乎一切正常,除了当我查看用户的书签,然后注销并重新登录,应用程序崩溃消息
$ b


*因未捕获异常'NSInternalInconsistencyException'而终止应用程序,原因:'无效更新:节中的行数无效0.更新(1)后,现有节中包含的行数必须等于更新前(2)节中包含的行数,加上或减去从该节插入或删除的行数( 1个插入,0个删除),加上或减去移入或移出该部分的行数(移入0个,移出0个)'
*



解决方案

viewWillDisappear 中设置 self。 tableViewDataSource = nil 。所以,你不会不正确地更新 dataSource


My app has a UITableViewController which uses a FirebaseTableViewDataSource (from FirebaseUI). The table shows the user's bookmarked posts correctly, but when I log that user off, and log another user in, the app crashes with the following message:

* 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).'*

I suspect the problem is related to how FirebaseUI updates the content of the tableView. I've being debugging this for the past 4 days; searched the SO questions; read the relevant docs but none mentions this unique issue. Any help will be much appreciated.

The Details (Sorry it's actually long)

This is my database structure:

|
+-posts
|   |
|   +-$postid
|        |
|        +-/* properties of a post: title, text, etc */
|
+-users
   |
   +-$userid
        |
        +-bookmarks
             |
             +-post1: true
             |
             +-post2: true

I am using FirebaseUI to show a user his/her bookmarks by passing the users/$userid/bookmarks ref to FirebaseTableViewDataSource as a query. Then for each key, I observe a single value event on posts/$postid in order to retrieve the post details...code below:

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
}

I put the above code in viewDidAppear and then remove the authStateListenerHandle in viewWillDisappear like so

override func viewWillDisappear(_ animated: Bool) {
    super.viewWillDisappear(animated)
    if let handle = self.authStateListenerHandle {
        FIRAuth.auth()?.removeStateDidChangeListener(handle)
    }
}

Almost everything works fine except, when I am viewing the bookmarks for a user, then log out and log back in, the app crashes with the message

* 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).' *

解决方案

In the viewWillDisappear set the self.tableViewDataSource = nil. So, that you don't update the dataSource improperly.

这篇关于FirebaseTableViewDataSource在用户注销和登录时崩溃的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆