Search code examples
google-cloud-firestoreswiftuifirebase-authenticationcombine

Firebase signInAnonymously using SwiftUI


Could anyone please help me with configuring the Firebase signInAnonymously? In fact, I am able to login anonymously. However, whenever I start a new simulator I get the error "There is no user logged in". The error disappears when restarting this new simulator, and then I am able to get the userId.

This is my initial code:

import SwiftUI
import Firebase

@main
struct DyeNotesApp: App {
    @UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate
    
    var body: some Scene {
        WindowGroup {
            ContentView() 
        }
    }
}

class AppDelegate: NSObject, UIApplicationDelegate {
    func application(_ application: UIApplication, didFinishLaunchingWithOptions laychOptions:
        [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
        
        FirebaseApp.configure()
            if Auth.auth().currentUser == nil {
                Auth.auth().signInAnonymously()
            }
        
        return true
    }
}

This is the class talking to Firebase:

class MainRepository: ObservableObject {
    private let path:String = "MainCollection"
    private let db = Firestore.firestore()
    @Published var model:[Model] = []
    
    init() {
        getData()
    }
    
    func getData() {
        if let userId = Auth.auth().currentUser?.uid {
            db.collection(path)
                .order(by: "createdTime", descending: true)
                .whereField("userId", isEqualTo: userId)
                .addSnapshotListener { (snapshot, error) in
                    if let snapshot = snapshot {
                        self.model = snapshot.documents.compactMap{ document in
                            do {
                                let x = try document.data(as: Model.self)
                                return x
                            }
                            catch {
                                print(error)
                            }
                            return nil
                        }
                    }
                }
        } else {
            print("There is no user logged in")
        }
    }

I found a solution in a youtube video comment: " ... capture the user id change via combine and trigger the snapshot monitoring when the user changes". But I don't know how to implement it.

Could anyone help me with the code for this solution? How can I implement a snapshot to monitoring when user changes?


Solution

  • I would suggest:

    1. to refactor your code to move
    if Auth.auth().currentUser == nil {
        Auth.auth().signInAnonymously()
    }
    

    from the app delegate to somewhere else, for simplicity you could put it in your MainRepository, but would be better to put it else where in some authentication component you can inject into this class.

    1. when you call .signInAnonymously() call it with a completion handler.
    Auth.auth().signInAnonymously { result, error in
    
    }
    
    

    you can then store the result object in memory which will contain a userid, and you can cal get data after successful login.

    Currently your app is calling to getData before the signing is complete. So it fails, it works on restart because the user is logged in from the previous session.