Firebase 快照未正确解析数据

Posted

技术标签:

【中文标题】Firebase 快照未正确解析数据【英文标题】:Firebase Snapshots not parsing data correctly 【发布时间】:2019-01-04 21:33:08 【问题描述】:

我正在尝试将经纬度坐标从 Firebase 下载到我的应用中,然后使用 Google Maps 和 Google Marker 在地图上显示一个标记。我知道地标功能有效,因为当我手动编程坐标时,我可以看到另一个“人”的占位符,所以这不是谷歌地图的问题。

问题似乎是双重的,第一,来自 Firebase 的数据正在“快照”,当您在控制台中执行“po 快照”时,一切都在那里,所有用户和数据。当我启动 for in 循环时,问题出在哪里。当您执行“po driver”时,它仅显示 firebase 中的第一个用户,但当您执行“po driverSnapshot”时,它确实显示与“po 快照”相同

由于某种原因,Firebase 不允许我正确解析快照。我将快照加载到字典中,我可以看到我的数据,但只能看到第一个用户,而不是其他用户。无论如何,我应该能够使用 ["my/example"] 作为字典的下标来提取坐标。当我尝试获取经度和纬度并将它们放入数组中时,我可以显示多个坐标(“快照”中所有用户的经度和纬度),这不起作用。

理想我想解决这两个问题。首先摆脱 Unexpectedly found nil 错误,然后弄清楚为什么当我有 3 个具有相同信息的用户时我只获得一个用户。

对我做错的任何帮助将不胜感激。我确实做了一个 pod Update 并且正在运行最新的 firebase。

这是我写的函数:

func loadMarkersFromFB1() 
    DataService.instance.REF_USERS.observeSingleEvent(of: .value, with:  (snapshot) in
        if let driverSnapshot = snapshot.children.allObjects as? [DataSnapshot] 
            for driver in driverSnapshot 
                    if driver.childSnapshot(forPath: ACCOUNT_PICKUP_MODE_ENABLED).value as? Bool == true 
                        if let driverDict = driver.value as? Dictionary<String, AnyObject> 
                            let coordinateArray = driverDict[DRIVERCOORDINATE] as! NSArray **THIS IS WHERE I AM GETTING NIL ERROR**
                            print(coordinateArray)
                            let driverCoordinate = CLLocationCoordinate2D(latitude: coordinateArray[0] as! CLLocationDegrees, longitude: coordinateArray[1] as! CLLocationDegrees)
                        //    DispatchQueue.main.async(execute: 
                                let othermarker = GMSMarker()
                                othermarker.position = driverCoordinate
                        //      othermarker.userData = snap
                                othermarker.icon = UIImage(named: "driverAnnotation")
                                othermarker.map = self.driverMapView
                        //    )
                        
                     else 
                        self.showAlert("Test")
                    
            
        
    )

这是 JSON:

 "users" : 
    "123456789123456789" : 
      "driver_profile" : 
        "currentlocation" : [ 55.55555, -55.55555555 ],
        "isDriverStatusPending" : false,
        "isPickupModeEnabled" : true,
        "is_userdriver" : true
      ,
      "first_name" : "Carlos",
      "last_name" : "Santana",
      "mobile_number" : "2125551212",
      "provider" : "Firebase"
    ,
    "2398472398472398472398472384" : 
      "driver_profile" : 
        "currentlocation" : [ 55.55555, -55.55555555 ],
        "isDriverStatusPending" : false,
        "isPickupModeEnabled" : true,
        "is_userdriver" : true
      ,
      "first_name" : "Mick",
      "last_name" : "Jagger",
      "mobile_number" : "3125551212",
      "provider" : "Firebase",
      "stripe_id" : "1234354954",
      "userAddressInfo" : 
        "Home" : 
          "City" : "Anywhere",
          "State" : "AA",
          "Street" : "123 Any Street",
          "Zip" : "12345"
        
      ,
      "userPhoto" : "http://www.myphoto.com"
    
  

【问题讨论】:

司机不应该只有一个用户,因为 driverSnapshot 是一个用户数组吗?另外,什么是零错误?您能告诉我们更多关于 DRIVERCOORDINATE 是什么的信息吗? 请添加来自REF_USERS的JSON,作为文本,不要截图。您可以通过单击Firebase Database console 上溢出菜单 (⠇) 中的“导出 JSON”链接来获取此信息。 使用 Swift 构造 Array 而不是 Obj-C NSArray 我也建议使用Any 而不是AnyObject。有可能将其转换为 NSArray 导致它为零。您是否尝试在失败线上方添加print(driverDict)?它打印什么? @Mocha 你是什么意思只使用1?是的 driverSnapshot 是用户数组,但我需要它遍历每个用户并查找 users/driver_profile/currentlocation 的值。 nil 错误是“Unexpectedly found nil while unwrapping an Optional value”。 DRIVERCOORDINATE 是一个常数。对不起,我应该编辑它。 is 是 firebase 路径 【参考方案1】:

您正在阅读/users,然后遍历它下面的子节点。这样就可以为您提供每个用户的快照,据我所知,它应该显示两个节点。

但是这段代码看起来很可疑:

if driver.childSnapshot(forPath: ACCOUNT_PICKUP_MODE_ENABLED).value as? Bool == true 

由于拾取模式状态为driver_profile/isPickupModeEnabled,您需要从该嵌套属性中读取。所以:

if driver.childSnapshot(forPath: "driver_profile/isPickupModeEnabled").value as? Bool == true 

这同样适用于您尝试从嵌套节点获取的任何属性。

【讨论】:

那只是一个常数,它指向那个路径。我直接试了还是不行 请确保您共享的代码没有我们无法知道其值的外部依赖项。让我们猜测值是浪费时间,并且会减少有人能够帮助您的机会。我强烈推荐阅读 how to create a minimal, complete, verifiable example 以获取有关如何执行此操作以及为什么有用的提示。【参考方案2】:

这个问题可能是由几个原因造成的

1) 根据弗兰克的回答,您的路径不正确

2) driver_profile子节点的处理

我采用了您的结构并将其导入 Firebase,然后更改了您的代码以使其正常工作。

首先是对问题中未包含的两个变量进行硬编码。第二件事是将 driver_profile 子节点视为它自己的字典,以从该节点中读取数据。

func loadMarkersFromFB1() 

    let ACCOUNT_PICKUP_MODE_ENABLED = "driver_profile/isPickupModeEnabled"
    let DRIVERCOORDINATE = "currentlocation"
    let ref = self.ref.child("users")
    ref.observeSingleEvent(of: .value, with:  (snapshot) in
        if let driverSnapshot = snapshot.children.allObjects as? [DataSnapshot] 
            for driver in driverSnapshot 
                if driver.childSnapshot(forPath: ACCOUNT_PICKUP_MODE_ENABLED).value as? Bool == true 
                    if let driverDict = driver.value as? Dictionary<String, AnyObject> 
                        let lastName = driverDict["last_name"] as! String
                        let childDict = driverDict["driver_profile"] as![String: Any] //**
                        let currentLocation = childDict[DRIVERCOORDINATE] as! NSArray
                        print(currentLocation[0], currentLocation[1])
                        print("\n")
                    
                 else 
                    print("error")
                
            
        
    )

结果是

55.55555 -55.55555555
55.55555 -55.55555555

当节点可能为 nil 时,您可能需要考虑额外的错误检查 - 例如,可以更好地保护某些可选项,以便在它们为 nil 的情况下,它们不会破坏您的代码。

如果路径导致问题,您应该接受 Franks 的回答。

【讨论】:

以上是关于Firebase 快照未正确解析数据的主要内容,如果未能解决你的问题,请参考以下文章

Firebase 实时数据库使快照更有价值

从 Firebase 数据库快照解析布尔值

UITableView 未加载 Firebase 快照数据。

XCode 未找到 Firebase v2.1.2(未找到框架错误)

使用 swiftyJSON/swift 从 Firebase 解析排行榜数据

Firebase 事件侦听器不起作用,我无法接收正确的快照