如何从实时数据库firebase中读取嵌套数据



我的数据库结构如下:

{
"username123" : {
"6642" : {
"latitude" : 37.861639,
"longitude" : -4.785556,
"name" : "CEPSA"
}
}
}

这个想法是,每个用户都会有一个最喜欢的加油站列表,由他们的ID标识(本例中为6642(。然而,我不知道如何获得这些数据。请帮忙吗?编辑:我试过了,但显然不起作用,因为我把整件事都拿回来了,我只是不知道如何获取id、纬度、经度和名称。

ref.child(user).getData(completion:  { error, snapshot in
guard error == nil else {
print(error!.localizedDescription)
return;
}
if let gasStationDict = snapshot.value as? [String:String] {
guard let id = snapshot.value, let name = gasStationDict["name"], let longitude = gasStationDict["longitude"], let latitude = gasStationDict["latitude"] else { return }
let gasStation = GasStation(name: name, longitude: longitude, latitude: latitude, favorita: true, id: id)
}
});

ref初始化如下:

var ref: DatabaseReference! = Database.database().reference()

用户为:

guard var user = UserDefaults.standard.string(forKey: "User") else { return }

主要问题是问题中提供的Firebase结构与代码不匹配:

user_id
gas_station_id
name

代码正试图像这样读取

if let gasStationDict = snapshot.value as? [String:String]

其中结构更像[String: [String: String]]或可能是[String: [String: Int]]

我建议使用.childSnapshot来获得深度嵌套数据的另一种解决方案。它更容易阅读,也更容易维护

我还建议改变结构。在NoSQL数据库中,通常最佳做法是将节点键与其包含的数据解除关联。

例如,在您的结构中,6642是站ID。如果将来站ID发生更改,该怎么办?实际上,你必须浏览整个数据库,搜索它,删除这些节点及其包含的任何内容,然后重新编写它们。啊!

这是一个结构更好的

{
"username123" : {
a_firebase_generated_node_key : { //using .childByAutoId to create
"latitude" : 37.861639,
"longitude" : -4.785556,
"name" : "CEPSA"
"station_id: "6652"
}
}
}

现在你可以更改电台的任何方面,而不必更改对它的任何引用。

然后使用childSnapshot读取和打印所有站点的代码

func printUsersGasStations() {
let ref = self.ref.child("gas_stations").child("username123")
ref.getData(completion: { error, snapshot in
if let err = error {
print(err.localizedDescription)
return
}

//this next line takes all of the stations and creates
//   an ordered array of them as DataSnapshots
let allStationsSnap = snapshot.children.allObjects as! [DataSnapshot]
for stationSnap in allStationsSnap {
let stationId = stationSnap.childSnapshot(forPath: "station_id").value as? String ?? "No Station ID"
let lat = stationSnap.childSnapshot(forPath: "lat").value as? Double ?? 0.0
let lon = stationSnap.childSnapshot(forPath: "lon").value as? Double ?? 0.0
let name = stationSnap.childSnapshot(forPath: "name").value as? String ?? "No Name"
print(stationId, lat, lon, name)
}
})
}

最新更新