Firebase快照无法正确解析数据

时间:2019-01-04 21:33:08

标签: swift firebase firebase-realtime-database

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

问题似乎是双重的,其一,Firebase中的数据被“捕捉”,当您在控制台中执行“ po快照”时,所有内容,所有用户和数据都已存在。当我启动for in循环时,问题就出在这里。当您执行“ po driver”时,它仅显示Firebase中的第一个用户,但是当您执行“ po driverSnapshot”时,它的显示与“ po snapshot”相同。

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

理想,我想解决两个问题。首先摆脱“意外发现nil”错误,然后弄清楚为什么只有3个具有相同信息的人才得到一个用户。

任何对我做错事的帮助将不胜感激。我确实做了一个pod更新,并且正在运行最新的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"
    }
  }
}

2 个答案:

答案 0 :(得分:2)

您正在阅读/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 {

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

答案 1 :(得分:1)

问题可能是由于几件事

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

当节点为零时,您可能要考虑其他错误检查-例如,某些可选参数可以得到更好的保护,因此,在节点为零的情况下,它们不会破坏您的代码。

如果路径引起了问题,您应该接受弗兰克斯的回答。