You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Swift UI手机号登录问题:无法触发新用户注册流程

SwiftUI手机号登录注册流程触发失败问题排查与修复

核心逻辑错误(最直接原因)

你的checkUser与loginWithOTP的布尔值判断逻辑完全颠倒:

  • checkUser中,用户不存在(documents.isEmpty)时返回completion(false)
  • 但loginWithOTP里却用if empty判断(期望empty为true时跳转注册视图)

这导致新用户场景下,empty拿到的是false,永远进不了跳转分支。

修正方案二选一:

方案1:调整checkUser的返回逻辑

让函数直接返回「用户是否不存在」的布尔值:

func checkUser(phNo: String, completion: @escaping BooleanCompletionHandler) {
    db.collection(FIRCollections.Profiles.rawValue).whereField("phoneNumber", isEqualTo: phNo).getDocuments { snapshot, error in
        // 先处理请求错误
        if let error = error {
            print("检查用户失败:\(error.localizedDescription)")
            completion(false)
            return
        }
        
        guard let snapshot = snapshot else {
            completion(false)
            return
        }
        
        // 直接返回「文档是否为空」的结果
        let isNewUser = snapshot.documents.isEmpty
        completion(isNewUser)
        print(isNewUser ? "用户不存在,需注册" : "用户已存在")
    }
}

方案2:保持checkUser不变,修改loginWithOTP的判断

针对原函数的返回值取反判断:

func loginWithOTP(completion: @escaping (Bool) -> Void) {
    FirebaseService.shared.checkUser(phNo: phNo) { userExists in
        // userExists为true表示用户已存在,取反判断是否需要注册
        if !userExists {
            print("otpverificationview empty confirmed")
            // SwiftUI状态必须在主线程更新
            DispatchQueue.main.async {
                showInfoView = true
            }
            return
        }
        // 处理老用户登录逻辑
        completion(true)
    }
}

其他必改点:UI状态更新需在主线程

Firebase的getDocuments回调运行在后台线程,SwiftUI的状态变量(如showInfoView)必须在主线程修改,否则状态更新可能不生效,所以一定要用DispatchQueue.main.async包裹状态修改代码。

补充:完善错误处理

原checkUser函数遇到请求错误时直接return,未调用completion,会导致loginWithOTP的回调永远不执行,流程卡住。必须在错误分支调用completion,给调用方明确结果。

内容的提问来源于stack exchange,提问作者durgxn

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 04:35:12