Firebase 查询结果 SWIFT 的奇怪行为
Posted
技术标签:
【中文标题】Firebase 查询结果 SWIFT 的奇怪行为【英文标题】:Strange behaviour on Firebase query result SWIFT 【发布时间】:2019-01-16 06:41:03 【问题描述】:我在 let itemToAdd = snapshot.childSnapshot(forPath: "Shop
a 从 Firebase 检索数据的函数行中收到此错误。
Could not cast value of type 'NSNull' (0x1118c8de0) to 'NSString' (0x10dda45d8).
中的控制台输出。
我要做的是通过一个值
opening Time
过滤数据库排序,而不是从快照中返回的条目中获取另一个值Shop Name
。
函数如下:
func filterOpenShops(enterDoStuff: @escaping (Bool) -> ())
ref = Database.database().reference().child("Continent").child("Europe").child("Country").child("Italy").child("Region").child("Emilia-Romagna").child("City").child("Bologna").child("Shops").child("Shops Opening Times")
let query = ref?.queryOrdered(byChild: "Opening Time").queryStarting(atValue: openingTimeQueryStart).queryEnding(atValue: openingTimeQueryEnd)
query?.observe(.value, with: (snapshot) in
for childSnapshot in snapshot.children
// new modification
if childSnapshot is DataSnapshot
let itemToAdd = snapshot.childSnapshot(forPath: "Shop Name").value as! String // gets the open shop from snapshot
self.availableShopsArray.append(itemToAdd)
print(snapshot.children)
print(" Open Shops are \(self.availableShopsArray)")
// still asynchronous part
enterDoStuff(true)
// call next cascade function filterClosedShops only when data
)
// Sychronous part
print("opening query start is \(openingTimeQueryStart) and opening query end is \(openingTimeQueryEnd)")
// end of filterOpenShops()
编辑:
I rewrote the function as:
func filterOpenShops(enterDoStuff: @escaping (Bool) -> ())
// get from Firebase snapshot all shops opening times into an array of tuples
//shopOpeningTimeArray:[(storeName: String, weekdayNumber: String, opening1: Sring, closing1: String, opening2:String, closing2: String)]
ref = Database.database().reference().child("Continent").child("Europe").child("Country").child("Italy").child("Region").child("Emilia-Romagna").child("City").child("Bologna").child("Shops").child("Shops Opening Times")
let query = ref?.queryOrdered(byChild: "Opening Time").queryStarting(atValue: String(describing: openingTimeQueryStart)).queryEnding(atValue: String(describing :openingTimeQueryEnd))
query?.observe(.value, with: (snapshot) in // original is ok
// guard let data = snapshot.value as? [String:String] else return
for childSnapshot in snapshot.children
print("snapshot is: \(childSnapshot)")
print("snapshot.childrend is: \(snapshot.children)")
guard let data = snapshot.value as? [String:String] else return
let itemToAdd = data["Shop Name"]
self.availableShopsArray.append(itemToAdd!)
print("Open Shop is: \(String(describing: itemToAdd))")
print(" Open Shops are \(self.availableShopsArray)")
// still asynchronous part
enterDoStuff(true)
// call next cascade function filterClosedShops only when data
print(" Open Shops are \(self.availableShopsArray)")
)
print("opening query start is \(openingTimeQueryStart) and opening query end is \(openingTimeQueryEnd)")
// end of filterOpenShops()
但我仍然得到一个空对象,而不是预期的 [String:String]。
在 Firebase 中创建条目的函数是:
func postOpeningTime()
// if shopNameTextfield.text != nil && openingTimeTextfield.text != nil && closingTimeTextfield.text != nil
let shopName = shopNameTextfield.text!
let openingTime = openingTimeTextfield.text!
let closingTime = closingTimeTextfield.text!
// else return
let post: [String:String] = [
"Shop Name" : shopName ,
"Opening Time" : openingTime ,
"Closing Time" : closingTime
]
var ref: DatabaseReference!
ref = Database.database().reference()
ref?.child("Continent").child("Europe").child("Country").child("Italy").child("Region").child("Emilia-Romagna").child("City").child("Bologna").child("Shops").child("Shops Opening Times").childByAutoId().setValue(post)
现在我有两种行为:
1st:当查询条目并找到 Int 值时:完成被调用,但我没有得到快照打印。 第二:查询条目并查找字符串值时:不会调用完成,但快照会打印带有值的正确条目。
任何人都可以看看这里发生了什么吗?
【问题讨论】:
您的店铺名称在某处为空。所以不要使用'as!'尝试使用“如果让” 我正在使用应该给我结果的搜索值。如何检查我获得的快照中的内容? 在运行 for 循环之前尝试记录 snapshot.children。您可能会看到值 我 printend childSnapshot 并且它有一个结果:`childSnapshot is: Snap (Arma Wed Mor) "Closing Time" = 41230; “开放时间”= 40830; “店铺名称” = Armaroli; ´ 所以查询正在寻找正确的数据。我只想从中获取店铺名称 @sanman。有趣的是,我将搜索重复到一个应该返回 2 家商店的值,但我仍然只得到与以前相同的值。可能是因为我在 for in 循环内打印childSnapshot
?我会尝试在循环之前打印snapshot.children
【参考方案1】:
我发现问题出在我投射查询结果的方式上。 将其转换为 [String:String] 生成返回,因为当条目参数的所有值都是 String 时,结果实际上是 [String[String:String]],但是当我将打开时间和关闭时间更改为 Int 时,我必须将快照读取为 [String[String:Any]]。 所以最终的功能是:
func filterOpenShops(setCompletion: @escaping (Bool) -> ())
// Empty the array for beginning of the search
self.availableShopsArray.removeAll()
var ref = Database.database().reference()
ref.child("Continent").child("Europe").child("Country").child("Italy").child("Region").child("Emilia-Romagna").child("City").child("Bologna").child("Shops").child("Shops Opening Times").queryOrdered(byChild: "Opening Time").queryStarting(atValue: openingTimeQueryStart).queryEnding(atValue: openingTimeQueryEnd).observe(.value) (snapshot) in
print(snapshot)
if let data = snapshot.value as? [String : [String : Any]]
for (_, value) in
data
let shopName = value["Shop Name"] as! String
let active = value["Active"] as! String
if active == "true"
self.availableShopsArray.append(shopName)
print("Shop_Name is :\(shopName)")
print("self.availableShopsArray is: \(self.availableShopsArray)")
else
print("No Shops")
// still asynchronous part
setCompletion(true)
// call next cascade function filterClosedShops only when data retrieving is finished
self.filterClosedShops(setCompletion: self.completionSetter)
print(" 1 Open Shops are \(self.availableShopsArray)")
// end of filterOpenShops()
【讨论】:
以上是关于Firebase 查询结果 SWIFT 的奇怪行为的主要内容,如果未能解决你的问题,请参考以下文章
Firebase/React/Redux 组件有奇怪的更新行为,状态应该没问题