在Swift中检查Firebase快照是否等于nil

7

我正在尝试查询Firebase,以检查是否有任何具有waiting: "1"的用户,然后当返回快照时,我想看看它是否等于nil。我已经尝试过这样做,但我使用的方法不起作用,只有在快照不等于nil时才有一些输出。我已经添加了我目前拥有的代码和来自Firebase的JSON文本。

import UIKit
import Firebase
import Spring

class GamesViewController: UIViewController {

let ref = Firebase(url: "https://123test123.firebaseio.com")
var activityIndicator: UIActivityIndicatorView = UIActivityIndicatorView()   

@IBAction func StartGamePressed(sender: AnyObject) {
    print("test1")
    var peopleWaiting: [String] = []

    let userRef = Firebase(url:"https://123test123.firebaseio.com/users")
    userRef.queryOrderedByChild("waiting").queryEqualToValue("1")
        .observeEventType(.ChildAdded, withBlock: { snapshot in
            print(snapshot.key)
            if snapshot.key == nil {
                print("test2")
                let userData = ["waiting": "1"]
                let usersRef = self.ref.childByAppendingPath("users")
                let hopperRef = usersRef.childByAppendingPath("\(self.ref.authData.uid)")

                hopperRef.updateChildValues(userData, withCompletionBlock: {
                    (error:NSError?, ref:Firebase!) in
                    if (error != nil) {
                        print("Data could not be saved.")
                        self.displayAlert("Oops!", message: "We have been unable to get you into a game, check you have an internet conection. If this problem carries on contect support")
                    } else {
                        print("Data saved successfully!")
                        let storyboard = UIStoryboard(name: "Main", bundle: nil)
                        let Home : UIViewController = storyboard.instantiateViewControllerWithIdentifier("continueToGame")
                        self.presentViewController(Home, animated: true, completion: nil)

                    }

                })


            } else {
                var randomUID: String
                peopleWaiting.append(snapshot.key)
                let randomIndex = Int(arc4random_uniform(UInt32(peopleWaiting.count)))
                randomUID = peopleWaiting[randomIndex]
                print(randomUID)
                let storyboard = UIStoryboard(name: "Main", bundle: nil)
                let Home : UIViewController = storyboard.instantiateViewControllerWithIdentifier("continueToGame")
                self.presentViewController(Home, animated: true, completion: nil)

            }
        })
}

func displayAlert(title: String, message: String){

    let formEmpty = UIAlertController(title: title, message: message, preferredStyle: UIAlertControllerStyle.Alert)
    formEmpty.addAction((UIAlertAction(title: "Ok", style: .Default, handler: { (action) -> Void in

    })))

    self.presentViewController(formEmpty, animated: true, completion: nil)
}

func activityIndicatorFunction(){

    activityIndicator = UIActivityIndicatorView(frame: CGRectMake(0, 0, 100, 100))
    activityIndicator.backgroundColor = UIColor(red:0.16, green:0.17, blue:0.21, alpha:1)
    activityIndicator.layer.cornerRadius = 6
    activityIndicator.center = self.view.center
    activityIndicator.hidesWhenStopped = true
    activityIndicator.activityIndicatorViewStyle = UIActivityIndicatorViewStyle.WhiteLarge
    view.addSubview(activityIndicator)
    activityIndicator.startAnimating()
    UIApplication.sharedApplication().beginIgnoringInteractionEvents()

}


}

JSON 数据:

{
"68e42b7f-aea5-4c3f-b655-51a99cb05bb0" : {
  "email" : "test1@test1.com",
  "username" : "test1",
  "waiting" : "0"
},
"8503d5a8-fc4a-492b-9883-ec3664898b4f" : {
  "email" : "test2@test2.com",
  "username" : "test2",
  "waiting" : "0"
}
}

请阅读关于“XY问题”的内容(因为我认为你的问题可能是“如何检测特定子元素是否存在?”),以及如何构建一个“最小、完整、可验证”的示例。如果您都注意到了,那么我们帮助您会更容易。 - Frank van Puffelen
2个回答

20

这里有几件事情需要注意,但最重要的是你不能使用.ChildAdded来测试子项是否存在。如果你仔细想一想,这是有道理的:当一个子项被添加到位置时,.ChildAdded事件会被触发。如果没有子项被添加,该事件就不会被触发。

因此,如果你想测试一个位置是否存在子项,你需要使用.Value。一旦你这样做了,就有各种方法来检测存在性。这里是其中一种方法:

ref.queryOrderedByChild("waiting").queryEqualToValue("1")
   .observeEventType(.Value, withBlock: { snapshot in
       print(snapshot.value)
       if !snapshot.exists() {
           print("test2")
       }
   });

4

检查 NSNull。这是观察节点的代码。查询的工作方式基本相同。

这是一个完整且经过测试的应用程序。要使用,请将字符串“existing”更改为您知道存在的路径,例如用户路径,并将“notexisting”更改为某个不存在的路径。

    let myRootRef = Firebase(url:"https://your-app.firebaseio.com")
    let existingRef = myRootRef.childByAppendingPath("existing")
    let notExistingRef = myRootRef.childByAppendingPath("notexisting")

    existingRef.observeEventType(.Value, withBlock: { snapshot in

        if snapshot.value is NSNull {
            print("This path was null!")
        } else {
            print("This path exists")
        }

    })

    notExistingRef.observeEventType(.Value, withBlock: { snapshot in

        if snapshot.value is NSNull {
            print("This path was null!")
        } else {
            print("This path exists")
        }

    })

请注意,使用.Value时,将保证返回结果并始终触发回调函数。如果您的代码使用.ChildAdded,则只有在存在子节点时才会触发该函数。
另外,请确保在Firebase中查看您的数据显示方式。
users
   user_0
     waiting: 1

如果不同于。
users
   user_0
     waiting: "1"

请注意,“1”与1不同。

它确实有效!我更新了我的答案,并附上了一个完整且经过测试的复制粘贴应用程序,我刚刚写好。如果您的代码无法正常工作,则可能存在其他问题-NSNull是正确的方法! - Jay
@Jay "我认为Firebase事务可能会返回一个无效的快照" 我们不会将快照传递到事务块中,而是传递当前值。当前值确实可以为空。但是你在这里没有使用事务,所以不影响结果。 - Frank van Puffelen
1
@FrankvanPuffelen 是的!你回答正确。我会把我的代码示例留给 NSNull 检查,因为它们是相互关联的。 - Jay
@Jay,我该如何在这个if语句中使用逻辑非运算符?if snapshot.value is NSNull。我想写成if snapshot.value !== NSNull { //},但它无法编译通过。谢谢。 - bibscy
1
@bibscy 尝试一下 if !(snapshot.value is NSNull) - Jay
显示剩余5条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接