ios - Firebase getDocument(querySnapshot)不起作用
问题描述
我正面临 Firebase 快照的问题。我成功地将我的 Fierbase 帐户与我的 Xcode 项目联系起来。我能够更改 Firestore 云中的数据。但我无法阅读。这是我的功能:
class UserService{
static func CheckIfMoreThanOneUserIsLoggedIn() -> Bool{
var BoolenToReturn:Bool?
let AuthUser = Auth.auth().currentUser
let userId = AuthUser!.uid
let localDeviceString = Constants.UserDefaultsStorage.string(forKey: userId)
// LocalDeviceString is generated (20 random letters) when the user is logged in succesfully.
//This DeviceString would be stored on one hand in the cloud on the other hand on the device.
//When the user open the Application it checks if the localDeviceString of the cloud is the same as the String stored on the device.
//I’m able to denie the user access through multiple devices simultaneously (-> Any imporvent is desired)
let newUserReference = Firestore.firestore().collection("users").document(userId)
newUserReference.getDocument {
(querySnapshot, err) in // Code never runs the closure
guard err != nil else {
return
}
for document in querySnapshot!.data()! {
if document.key == "RandomString" {
let docValue:String = document.value as! String
if docValue == localDeviceString{
BoolenToReturn = true
}
else{
BoolenToReturn = false
}
}
}
}
return BoolenToReturn ?? false
}
}
编辑
基于@Frank van Puffelen 的链接,我能够制定自己的解决方案。但是这个程序并没有我想要的那么专业,因为现在它是一个在LaunchViewController
. 此外,我将 segueHomeViewController
称为newUserReference.getDocument
. 我不想实现的目标:在 UserService 类中定义的一个函数,如果允许用户使用该应用程序,它将返回一个布尔值。
解决方案
我想你可能想调查一个完成处理程序。这个想法是调用一个异步函数,然后在该函数完成时执行一个任务。下面的代码几乎可以直接应用于您的问题的解决方案。
所以这是一个你可以开始的例子。假设我们有一个用户存储在用户集合中的应用程序
users
uid_0
name: "Steve"
uid_1
name: "Danno"
uid_2
name: "Junior"
uid_3
name: "Tani"
一个新用户想要注册,但该应用程序不允许重复名称。因此,我们需要查询我们的 users 集合以确定该名称是否已被使用。这是调用查询函数的代码。
self.doesUserNameExist(userName: "Steve" ) { doesExist in
if doesExist == true {
print("yep, it exists")
} else {
print("Nope - it's not there")
}
}
print("this code will execute before the above code")
那将打印是的,它存在
这是执行查询的实际函数。请注意我们如何使用完成处理程序,即在完成时@escaping 闭包。
//determine if a user name exists in Firestore, return true if it does, false if not
func doesUserNameExist(userName: String, completion: @escaping( (Bool) -> Void) ) {
let usersCollection = self.db.collection("users")
usersCollection.whereField("name", isEqualTo: userName).getDocuments(completion: { querySnapshot, error in
if let err = error {
print(err.localizedDescription)
return
}
guard let docs = querySnapshot?.documents else { return }
if docs.count > 0 {
completion(true)
} else {
completion(false)
}
})
}
这是从异步函数“返回”数据的典型方式,因为它允许函数执行,数据有效,然后以异步方式将该数据传递回调用函数。
请注意,调用函数之后的任何代码,如下所示
print("this code will execute before the above code")
将在函数闭包中的代码之前执行。
编辑
上面的这个调用是这样调用的
self.doesUserNameExist(userName: "Jay", completion: { doesItExist in
print(doesItExist)
})
推荐阅读
- ruby-on-rails - 由于将 rails 从 3 迁移到 5,升级配置更少
- bash - 关闭执行命令的返回消息
- mysql - MySQL查找给定字段的MAX并返回整行
- .net - Is it possible to use ASP .Net Core 3.1 from a library that targets .NET Standard 2.x?
- javascript - Electron 未正确加载 index.html,本地文件夹中的文件未加载
- css - 如何使用 PostCss 编译 CSS 变量
- mysql - SQL 使用 WHERE 子句和来自多个表的 ALIASING 数据
- java - Java - 在除以双精度时无法将双精度转换为整数
- apache-spark - 如何优雅地停止 spark dStream 进程
- python - 基于可用参数的动态函数签名?