简体   繁体   English

处理复杂的Firebase数据库查询的空返回

[英]handling null return from complex firebase database queries

I have a search feature built into my app that filters users from my firebase database. 我的应用程序内置了搜索功能,可以从Firebase数据库中过滤用户。

I am able to do this correctly to an extent. 我能够在一定程度上正确地做到这一点。 The issue is whenever I search for a user that doesn't exist the app crashes with the error: Index out of range 问题是,每当我搜索不存在的用户时,应用程序就会崩溃并显示以下错误: Index out of range

These are UICollectionViewCells so I handle the cells returned in numberOfItemsInSection and I thought I had coded for the condition nil or zero but apparently not. 这些是UICollectionViewCells,所以我处理numberOfItemsInSection中返回的单元格,我以为我已为条件nil或零编码,但显然不是。

Here is where the search is performed 这是执行搜索的地方

func searchUsers(searchText: String) {

    let ref = Database.database().reference()
    ref.child("users").queryOrdered(byChild: "name").queryStarting(atValue: searchText).queryEnding(atValue: "\(searchText)\u{f8ff}")
        .observe(.childAdded, with: {(snapshot) in

            if let dictionary = snapshot.value as? [String: AnyObject] {
                let user = User()
                user.setValuesForKeys(dictionary)

                self.users.append(user)
                print(snapshot)

                DispatchQueue.main.async(execute: {
                    self.collectionView?.reloadData()
                })
            }

                print(self.users.count)
        }, withCancel: nil)

}

Any suggestions? 有什么建议么?

you should not return Int() from the numberOfItemsInSection return 0 instead 您不应该从numberOfItemsInSection返回Int()返回0

override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
   switch section {
   case 0:
      return users.count
   case 1:
     // handle based on section 1 datasource count
}

After carefully reading the documentation I was able to deduce the source of the error. 仔细阅读文档后,我可以推断出错误的来源。 Here is a line from the FireBase documentation: 这是FireBase文档中的一行:

"If no data exists at the specified location, the FDataSnapshot will return an NSNull." “如果指定位置不存在数据,则FDataSnapshot将返回NSNull。”

So to circumnavigate the error normally you would be able to add something along the lines of: 因此,通常可以通过以下方式添加一些内容来规避错误:

if snapshot.value == NSNULL {

    print("no users returned") 
} else {
//do something with data

However, with the FireBase query I was performing, the observation was that of .childAdded events. 但是,在执行FireBase查询时,观察到的是.childAdded事件。

The FireBase documentaion calls these queries, complex queriers. FireBase文档将这些查询称为复杂查询器。 In my case I was using .queryStarting and .queryEnding which only return .childAdded events so checking the value wouldn't work inside the query parameters and the application would crash. 在我的情况下,我使用的是.queryStarting.queryEnding ,它们仅返回.childAdded事件,因此,无法查询参数检查该值,并且应用程序将崩溃。

The solution is to check if the query returns null BEFORE you preform the search. 解决方案是执行搜索之前检查查询是否返回null。

This is especially important if you are using the data to return something like collectionView or tableView Cells. 如果您使用数据返回诸如collectionView或tableView Cells之类的数据,则这一点尤其重要。

So to wrap up, all I had to do, was simply add a reference observation on the query return value before I used it to create my UICollectionViewCells. 总结一下,我要做的就是在使用查询返回值创建UICollectionViewCells之前简单地添加一个参考观察值。 That ended up looking like this. 最终看起来像这样。

ref.observe(.value, with: { snap in
    if snap.value is NSNull {
        print("no users returned")
        self.users.removeAll()

        DispatchQueue.main.async(execute: {
        self.collectionView?.reloadData()
        })

    }
})

Hope this helps someone. 希望这对某人有帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM