我正在将实时数据库与Google的Firebase一起使用,并且试图检查子值是否与某个值匹配。
我有一组存储在Firebase数据库中的用户。 每个用户对象都包含一个令牌字段。
{
"users" : {
"-LTTvwvs5OMaKO6pyZb-" : {
"accountId" : 1001,
"createdAt" : "2018-12-11 15:22:55",
"email" : "john@doe.com",
"fcmToken" : "duhfkNCIKW8:APA91bGgbzVCcagIhIw8DYFN_LVIKcjtyUiZEk0mxd3QLYkxRjQuGXdSfZMPcvw4maytKef-GXMEFrpH_lLz5QY0OV7qvwtyOll9jjKMH0vEWJUGIyp1iGQ4NZIMQE3kmZ-jZ8kF-1Bc",
"updatedAt" : "2018-12-11 15:22:55"
},
"-LTTwH8BdMe6W1lmhb-b" : {
"accountId" : 1001,
"createdAt" : "2018-12-11 15:24:22",
"email" : "john@doe.com",
"fcmToken" : "e_86qbjpjLE:APA91bHyVEgeH8aZMrn7213ws0-oXeTpdFRwY-FDcAbkQkMnaCdSNp9he6-AvQ0AUIsX-TywAxuWLCZ9BqIRsuyx1ZD9reD6wMeqtfP1swONq-rF6vQzet61DUbLfPXdlZhvxEjI9Cpz",
"updatedAt" : "2018-12-11 15:24:22"
},
"-LTTwNcoaQYri1paUwVD" : {
"accountId" : 1001,
"createdAt" : "2018-12-11 15:24:48",
"email" : "john@doe.com",
"fcmToken" : "e_86qbjpjLE:APA91bHyVEgeH8aZMrn7213ws0-oXeTpdFRwY-FDcAbkQkMnaCdSNp9he6-AvQ0AUIsX-TywAxuWLCZ9BqIRsuyx1ZD9reD6wMeqtfP1swONq-rF6vQzet61DUbLfPXdlZhvxEjI9Cpz",
"updatedAt" : "2018-12-11 15:24:48"
},
"-LTUv-aBEaQDrvvMrlAG" : {
"accountId" : 1001,
"createdAt" : "2018-12-11 18:58:25",
"email" : "john@doe.com",
"fcmToken" : "eOaNDdd2DXI:APA91bGzgcudlScng9TuEgSUY9ahA2pXVgl7AKxmkdX9ubw6uA5livNcJUlcI5pHYwn9fI7kc_9od5AbGrXm4wZPul_gI7qcGarTQTwkxq9zEKgovX0nWDDpDtNCLiWIaON6MWu5XLbW",
"updatedAt" : "2018-12-11 18:58:25"
}
}
}
另一方面,我的手机上有 1个令牌
例如
“ duhfkNCIKW8:APA91bGgbzVCcagIhIw8DYFN_LVIKcjtyUiZEk0mxd3QLYkxRjQuGXdSfZMPcvw4maytKef-GXMEFrpH_lLz5QY0OV7qvwyOll1jJKQK4K1KJKIK4K
我正在尝试将该令牌与Firebase数据库中的所有令牌进行比较。
func storeToFirebaseDatabase() {
let ref = Database.database().reference()
let usersRef = ref.child("users")
let id = usersRef.childByAutoId().key
let fcmToken = UserDefaults.standard.string(forKey: "fcmToken")
consoleLog(fcmToken)
let values =
["accountId": loginAccount.id!,
"email": loginAccount.username,
"fcmToken": fcmToken
] as [String : Any]
ref.root.child("users").observe(DataEventType.value, with: { (snapshot) in
if snapshot.exists() {
for child in snapshot.children {
let token = (child as! DataSnapshot).childSnapshot(forPath: "fcmToken").value as! String
if(token != fcmToken){
usersRef.child(id!).setValue(values, withCompletionBlock: { (err, ref) in
if err != nil {
print(err.self as Any)
return
}
print("Successfully saved user in Firebase DB")
})
break
}
}
}
}) { (error) in
print(error.localizedDescription)
}
}
由于某些原因,令牌仍在继续插入,好像我的if-check一直在工作。
如何进一步调试呢?
答案 0 :(得分:1)
您可以将HashMap()与setValue
一起使用,而不是updateChildValues
,如果令牌不同,它将覆盖;如果令牌相等,它将不更新令牌并覆盖当前令牌。
而且您可以防止查询数据库以获取该值并将其与if语句进行比较。
您应将此行替换为updateChildValues
而不是setValue
usersRef.child(id!).setValue(values....
在这里看看:
https://firebase.google.com/docs/database/ios/read-and-write
从文档中
在没有节点的情况下同时写入节点的特定子节点 要覆盖其他子节点,请使用updateChildValues方法。
在调用updateChildValues时,您可以更新较低级别的子级 通过指定键的路径来获取值。
答案 1 :(得分:1)
您的问题是,您将if语句中的令牌与每个用户进行比较,但是您需要查看用户是否拥有
ref.root.child("users").observe(DataEventType.value, with: { (snapshot) in
if snapshot.exists() {
let tokens = snapshot.children.forEach { ($0 as! DataSnapshot).childSnapshot(forPath: "fcmToken").value as! String }
if ! tokens.contains(fcmToken) {
// no user has that token , set the user here
}
}
}
答案 2 :(得分:1)
我可能对这个问题有一个误解,但似乎您想要在Firebase中不存在给定令牌的情况下创建用户。
一个简单的查询即可;
let usersRef = self.ref.child("users")
let tokenToCompare = "duhfkNCIKW8APA9..." //abbreviated
let query = usersRef.queryOrdered(byChild: "fcmToken").queryEqual(toValue: tokenToCompare)
query.observe(.value, with: { snapshot in
if snapshot.exists() {
print("token exists, do not create user")
return
} else {
print("no existing token found, create user")
}
})
如果令牌存在,它将打印该消息,并且不会继续。如果令牌不存在,则可以插入代码以创建用户。
...如果您想对所有令牌进行非规范化,请添加一个单独的节点以跟踪现有令牌
existing_tokens
jasoijaisas9: true
99i9kmkdodkf: true
duhfkNCIKW8APA9: true
那么您可以通过简单的观察来避免繁重的查询,因为它重量轻得多。
let existingTokensRef = self.ref.child("existing_tokens")
let tokenToFindRef = existingTokensRef.child("duhfkNCIKW8APA9")
tokenToFindRef.observeSingleEvent(of: .value, with: { snapshot in
if !snapshot.exists() {
print("ok to create user")
} else {
print("token exists! Dont create user")
}
})
此技术唯一值得一看的是键中没有special characters。