【问题标题】:Checking if Firebase snapshot is equal to nil in Swift在 Swift 中检查 Firebase 快照是否等于 nil
【发布时间】:2016-06-11 11:54:51
【问题描述】:

我正在尝试查询 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 problem(因为我认为您的问题可能是“我如何检测某个孩子是否存在?”)以及如何构建minimal, complete, verifiable example。如果您兼顾两者,我们会更容易为您提供帮助。

标签: json swift firebase arc4random


【解决方案1】:

这里发生了一些事情,但最重要的是您无法使用.ChildAdded 测试孩子的存在。如果您考虑一下,这是有道理的:将孩子添加到该位置时会引发 .ChildAdded 事件。如果没有添加孩子,则不会引发事件。

所以如果你想测试一个位置是否存在一个孩子,你需要使用.Value。一旦你这样做了,就有多种方法可以检测存在。这是一个:

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

【讨论】:

    【解决方案2】:

    检查 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
    • 如果您的参考或查询格式错误或应用程序设置不正确,可能会导致各种问题。我建议复制并粘贴您的代码作为测试方法,并删除除基本必需品之外的所有内容,并逐步检查您的代码以查看它在哪里不起作用。
    • @FrankvanPuffelen 是的!你有正确的答案。我将把我的留给 NSNull 检查代码示例,因为它们携手并进。
    • @bibscy try if !(snapshot.value is NSNull)
    猜你喜欢
    • 2023-04-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-05
    • 1970-01-01
    • 2016-05-27
    • 1970-01-01
    相关资源
    最近更新 更多