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

基于Firebase的账号密码登录APP,如何判断用户登录状态

Hey there! Let's break down how to check the user's login status after closing your LoginViewController, given your Firebase Realtime Database setup:

While you're maintaining a loggedIn field in your Users node, Firebase Auth already handles user session persistence and state tracking out of the box. You can combine this with your custom node to double-check the status:

import FirebaseAuth
import FirebaseDatabase

// Add this listener in your AppDelegate, SceneDelegate, or a global state manager class
Auth.auth().addStateDidChangeListener { auth, user in
    if let currentUser = user {
        // User is authenticated via Firebase Auth, now verify your custom `loggedIn` status
        let userRef = Database.database().reference().child("Users").child(currentUser.displayName ?? currentUser.uid)
        // Replace with your actual username key if you're using that instead of UID
        
        userRef.observeSingleEvent(of: .value) { snapshot in
            guard let userData = snapshot.value as? [String: Any],
                  let loggedInStatus = userData["loggedIn"] as? String,
                  loggedInStatus == "true" else {
                // Custom status doesn't match, treat as logged out
                // Redirect to LoginViewController here
                return
            }
            
            // User is fully logged in, proceed to main app flow
        }
    } else {
        // No authenticated user, redirect to login
    }
}

2. Directly Check Your Custom loggedIn Field

If you want to rely solely on your Users node's loggedIn attribute, you'll need to persist the current username locally (e.g., via UserDefaults) when login succeeds, then fetch the remote status when needed:

One-Time Check (Great for App Launch)

import FirebaseDatabase

// Fetch the saved username first
guard let currentUsername = UserDefaults.standard.string(forKey: "currentLoggedInUsername") else {
    // No saved username = user isn't logged in
    return
}

// Pull the user's data from Firebase
let userRef = Database.database().reference().child("Users").child(currentUsername)
userRef.observeSingleEvent(of: .value) { snapshot in
    guard let userData = snapshot.value as? [String: Any],
          let loggedIn = userData["loggedIn"] as? String,
          loggedIn == "true" else {
        // User isn't marked as logged in in the database
        // Clear local saved data and redirect to login
        UserDefaults.standard.removeObject(forKey: "currentLoggedInUsername")
        return
    }
    
    // User is logged in, continue with main app
}

Real-Time Listener (For Live Status Updates)

If you need to react immediately if the loggedIn status changes (e.g., from another device), use a real-time observer:

guard let currentUsername = UserDefaults.standard.string(forKey: "currentLoggedInUsername") else {
    return
}

let userRef = Database.database().reference().child("Users").child(currentUsername)
userRef.observe(.value) { snapshot in
    guard let userData = snapshot.value as? [String: Any],
          let loggedInStatus = userData["loggedIn"] as? String else {
        return
    }
    
    if loggedInStatus == "true" {
        // Maintain logged-in state
    } else {
        // Status changed to logged out - clear local data and redirect
        UserDefaults.standard.removeObject(forKey: "currentLoggedInUsername")
        // Navigate back to LoginViewController
    }
}

3. Combine Local Persistence with Remote Validation

For faster initial checks, save the login status locally when login succeeds, then verify against Firebase to ensure consistency:

// When login succeeds in LoginViewController:
UserDefaults.standard.set(currentUsername, forKey: "currentLoggedInUsername")
UserDefaults.standard.set("true", forKey: "localLoginStatus")
UserDefaults.standard.synchronize()

// When checking status later:
let isLocallyLoggedIn = UserDefaults.standard.string(forKey: "localLoginStatus") == "true"
guard let username = UserDefaults.standard.string(forKey: "currentLoggedInUsername"), isLocallyLoggedIn else {
    // Local state says logged out, redirect to login
    return
}

// Verify with Firebase to confirm
let userRef = Database.database().reference().child("Users").child(username)
userRef.observeSingleEvent(of: .value) { snapshot in
    guard let userData = snapshot.value as? [String: Any],
          let remoteStatus = userData["loggedIn"] as? String,
          remoteStatus == "true" else {
        // Remote status doesn't match local - update local state
        UserDefaults.standard.set("false", forKey: "localLoginStatus")
        // Redirect to login
        return
    }
    
    // Both local and remote confirm login, proceed
}

Important Notes:

  • Secure Your Database Rules: Make sure only the authenticated user can modify their own loggedIn field. Example rule:
    "Users": {
      "$username": {
        ".write": "auth != null && auth.token.name == $username"
      }
    }
    
  • Clean Up on Logout: When the user logs out, set loggedIn to "false" in Firebase, and clear all local persisted data.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 07:53:56