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

Swift+Firebase师生APP:登录后基于Firestore角色跳转ViewController问题

Swift + Firebase 登录状态判断与角色跳转修复方案

你的代码核心问题

  • 强制解包UID,用户未登录时currentUser为nil会直接崩溃
  • 错误逻辑完全搞反:error == nil是成功获取文档,你却跳注册页;有错误反而跳主页面
  • 完全没解析Firestore里的用户角色字段,缺失角色判断逻辑
  • 未单独处理「用户未登录」的分支

修正后的完整逻辑代码

// 先判断用户是否已登录
guard let currentUser = Auth.auth().currentUser else {
    // 未登录:跳转到认证页面(登录/注册)
    if let authVC = storyboard?.instantiateViewController(withIdentifier: "SignUpViewControllerID") {
        GetWindow()?.rootViewController = authVC
        GetWindow()?.makeKeyAndVisible()
    }
    return
}

// 已登录:获取用户UID并从Firestore拉取数据
let uid = currentUser.uid
let db = Firestore.firestore()
db.collection("Users").document(uid).getDocument { snapshot, error in
    // 处理请求错误
    if let error = error {
        print("获取用户数据失败:\(error.localizedDescription)")
        // 错误场景:跳转登录页或错误提示页
        if let authVC = self.storyboard?.instantiateViewController(withIdentifier: "SignUpViewControllerID") {
            GetWindow()?.rootViewController = authVC
            GetWindow()?.makeKeyAndVisible()
        }
        return
    }
    
    // 确保文档存在且有数据
    guard let snapshot = snapshot, snapshot.exists, let userData = snapshot.data() else {
        print("用户文档不存在或无数据")
        // 文档不存在:可能是新用户,跳转完善资料页或登录页
        if let authVC = self.storyboard?.instantiateViewController(withIdentifier: "SignUpViewControllerID") {
            GetWindow()?.rootViewController = authVC
            GetWindow()?.makeKeyAndVisible()
        }
        return
    }
    
    // 解析用户角色(假设Firestore文档里有"role"字段,值为"student"或"tutor")
    guard let role = userData["role"] as? String else {
        print("用户角色字段缺失")
        // 角色缺失:跳转完善资料页
        if let profileVC = self.storyboard?.instantiateViewController(withIdentifier: "完善资料页面ID") {
            GetWindow()?.rootViewController = profileVC
            GetWindow()?.makeKeyAndVisible()
        }
        return
    }
    
    // 根据角色跳转对应页面
    switch role {
    case "student":
        if let studentTabBar = self.storyboard?.instantiateViewController(withIdentifier: "StudentTabBarControllerID") {
            GetWindow()?.rootViewController = studentTabBar
            GetWindow()?.makeKeyAndVisible()
        }
    case "tutor":
        if let tutorTabBar = self.storyboard?.instantiateViewController(withIdentifier: "TutorTabBarControllerID") {
            GetWindow()?.rootViewController = tutorTabBar
            GetWindow()?.makeKeyAndVisible()
        }
    default:
        print("未知用户角色")
        // 未知角色:跳转完善资料页或登录页
        if let authVC = self.storyboard?.instantiateViewController(withIdentifier: "SignUpViewControllerID") {
            GetWindow()?.rootViewController = authVC
            GetWindow()?.makeKeyAndVisible()
        }
    }
}

关键说明

  1. 安全判断登录状态:用guard let替代强制解包,避免崩溃
  2. 正确错误处理:先处理网络请求错误,再覆盖文档不存在、字段缺失等异常情况
  3. 角色解析与跳转:明确解析Firestore中的role字段,根据不同角色跳转到对应页面
  4. 异常场景覆盖:针对文档不存在、角色缺失等情况,都做了合理的跳转处理

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 18:10:35