我想使用Firebase Auth进行电子邮件/密码注册。问题是,当使用的电子邮件地址也经过验证时,我只想接受经过身份验证的用户。
通常,我们可以使用侦听器来检查用户何时登录或不再登录:
Auth.auth().addStateDidChangeListener { (auth, user) in
Run Code Online (Sandbox Code Playgroud)
问题是,当用户单击验证电子邮件中的链接时,不会触发此侦听器。创建帐户后才调用它。
在等待用户单击链接时,可以循环执行以下操作:
Auth.auth().currentUser!.reload() {
if !Auth.auth().currentUser!.isEmailVerified {
Run Code Online (Sandbox Code Playgroud)
但是问题是我理想上要管理侦听器回调中的所有身份验证内容,但是当电子邮件验证状态更改时不使用侦听器。
我有什么想念的吗?
我知道在移动设备上您可以使用深层链接,因此邮件中的链接将再次打开该应用程序,但这不是我想要的,因为用户可以在其计算机上打开邮件,因此问题仍然需要解决。
目前,我看到的唯一解决方案是自己发送nsnotification并在我处理所有auth代码的地方进行处理,但感觉有些混乱。
有没有一种方法可以使@Published变量仅在新值与旧值不同时才发布其值?
现在如果我们有
@Published var test: Bool = false
我们做
test = false
test = false
test = false
Run Code Online (Sandbox Code Playgroud)
发布者被呼叫 3 次。这是非常烦人的,因为它有时会导致我的 SwiftUI 视图被重新创建,因为在层次结构中较高的某个位置,发布者被设置为之前设置的值,通过另一个被触发的发布者(并且会破坏文本字段输入,因为视图模型通过当发生这种情况时,层次结构将被重新创建)。
有没有一种方法只在从 到false或true从 到 时才发布?
一个示例场景:
我们在应用程序中创建一个用户对象,并且想要向该用户添加一辆车。如果没有找到汽车,应用程序应立即显示“添加汽车”视图,否则显示主应用程序视图。为此,我们在某处有一个监听器。在我们的顶层视图中,我们有:
@ObservedObject var viewModel = UserViewModel()
var body: some View {
if !viewModel.hasVehicles {
return AnyView(AddVehicleView(viewModel:AddVehicleViewModel())
} else {
return AnyView(UserMainView(user: user))
}
}
}
Run Code Online (Sandbox Code Playgroud)
在我们的UserViewModel我们有
class UserViewModel: ObservableObject {
@Published var hasVehicles: Bool = false
Run Code Online (Sandbox Code Playgroud)
在里面AddVehicleView我们有一个表单,允许用户填写一些文本字段并保存车辆。
现在想象一下,由于某种原因,更新属性的代码hasVehicles被触发,但仍然没有车辆。会发生什么:
hasVehicles …
我想在(非全屏)模式对话框下面的全屏div上执行单击.然而,似乎click事件自动以我的背景div的中心为目标,从而触及位于该div之上的内容(模态对话框本身).
如何指定点击发生的位置?
这是我的click命令的详细输出:
Element is not clickable at point (640, 436). Other element would receive the click: <label class="btn btn-default ">...
我找到了使用MergeManyor组合发布商的方法CombineLatest,但在我的特定情况下似乎没有找到解决方案。
例子:
class Test {
@Published var firstNameValid: Bool = false
@Published var lastNameValid: Bool = false
@Published var emailValid: Bool = false
@Published var allValid: Bool = false
}
Run Code Online (Sandbox Code Playgroud)
我想allValid成为false当任何以前的出版商被设置为false,并且true如果他们全部都是true。我也不想对我正在观察的发布商列表进行硬编码,因为我想要一个灵活的解决方案,所以我希望能够将Bool发布商数组传递给我用来执行此操作的任何代码。
我试过这个
let fieldPublishers = [$firstNameValid, $lastNameValid, $emailValid]
Publishers
.MergeMany(fieldPublishers)
.sink { [weak self] values in
self?.allValid = values.allSatisfy { $0 }
}
.store(in: &subscribers)
Run Code Online (Sandbox Code Playgroud)
但这当然行不通,因为我得到的是发布者数组,而不是值数组。sink我尝试了一些其他方法(忘记了哪些方法),但它们似乎只有在我在执行期间为所有 3 个发布者分配了一个值时才会调用。
在只使用 2 个发布者的情况下,我设法使用CombineLatest …
我有以下结构
struct Vehicle: Codable, Identifiable {
@DocumentID var id: String?
var name: String
}
Run Code Online (Sandbox Code Playgroud)
只要我使用默认的 Swift 解码器,我就可以毫无问题地加载 Firestore 条目(使用document.data(as:),并且id包含文档 ID。
然而,我现在需要在该结构中使用自定义解码函数,这就是出现问题的地方。
我可以毫无问题地加载所有字段,但文档 ID 未填写。
我尝试这样:
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
if let id = try container.decodeIfPresent(DocumentID<String>.self, forKey: .id) {
self.id = id.wrappedValue
}
Run Code Online (Sandbox Code Playgroud)
但它给了我nil。
我找到了一些其他答案,但他们讨论了DocumentReference哪种类型不存在(或不再存在?)。
我该如何解决这个问题?
谢谢