0

我已经在我的应用程序中设置了我的 Firebase 身份验证来注册用户并保存他们的注册信息,这非常有效。但是,当我尝试获取数据以填充他们的个人资料屏幕(使用他们的姓名、个人资料图片等)时,应用程序崩溃了,说它打开了一个可选值,结果为 nil。我做了一个打印功能,显示信息是否实际上是从 Firestore 中提取的。我不确定为什么每次尝试加载我的个人资料屏幕时它都会崩溃。是我做错了什么还是Auth有问题?

用户型号代码:

import SwiftUI
import Foundation

struct User: Encodable, Decodable{

var uuid: String
var email: String
var profileImageUrl: String
var firstname: String
var lastname: String 
}

认证服务

import Foundation
import Firebase
import FirebaseAuth
import FirebaseStorage
import FirebaseFirestore


class AuthService {

static var storeRoot = Firestore.firestore()

static func getUserId(userid: String) -> DocumentReference {
    return storeRoot.collection("users").document(userid)
}

static func signUp(firstname: String, lastname:String, email: String, password: String, imageData: Data, onSuccess: @escaping (_ user: User) -> Void, onError: @escaping(_ errorMessage: String) -> Void) {
    
    Auth.auth().createUser(withEmail: email, password: password) {
        (authData, error) in
        
        if error != nil {
            onError(error!.localizedDescription)
            return
        }
        guard let userId = authData?.user.uid else {return}
        
        let storageProfileUserId = StorageService.storageProfileId(userId: userId)
        
        let metadata = StorageMetadata()
        metadata.contentType = "image/jpg"
        
        StorageService.saveProfileImage(userId: userId, firstname: firstname, lastname: lastname, email: email, imageData: imageData, metaData: metadata, storageProfileImageRef: storageProfileUserId, onSuccess: onSuccess, onError: onError)
    }
}


static func signIn(email: String, password: String, onSuccess: @escaping (_ user: User) -> Void, onError:
                    @escaping(_ errorMessage: String) -> Void) {
    
    Auth.auth().signIn(withEmail: email, password: password){
        (authData, error) in
        
        if error != nil {
            onError(error!.localizedDescription)
            return
        }
        
        guard let userId = authData?.user.uid else {return}
        
        let firestoreUserId = getUserId(userid: userId)
        
        firestoreUserId.getDocument{
            
            (document, error) in
           if let dict = document?.data() {
                guard let decodedUser = try? User.init(fromDictionary: dict) else {return}
            
            onSuccess(decodedUser)
            }
        }
    }
}

}

会话存储:

class SessionStore: ObservableObject {
    
    private var db = Firestore.firestore()
    
    var didChange = PassthroughSubject<SessionStore, Never>()
    @Published var session: User? {
        didSet { self.didChange.send(self) }
    }
    
    var handle: AuthStateDidChangeListenerHandle?
    
    func listen() {
        handle = Auth.auth().addStateDidChangeListener({ (auth, user) in
            if let user = user {
                let firestoreUserId = AuthService.getUserId(userid: user.uid)
                firestoreUserId.getDocument { (document, error) in
                    if let dict = document?.data() {
                        guard let decodedUser = try? User.init(fromDictionary: dict) else { return }
                        let dataDescription = document?.data().map(String.init(describing:)) ?? "nil"
                        print("Document data: \(dataDescription)")
                        self.session = decodedUser
                    }
                }
            } else {
                print("User not found")
                self.session = nil
            }
        })
        
    }
    
    func logout() {
        do {
            try Auth.auth().signOut()
        } catch {
            
        }
    }
    
    func unbind() {
        if let handle = handle {
            Auth.auth().removeStateDidChangeListener(handle)
        }
    }
    
    deinit {
        unbind()
    }
}

这是当我尝试解开值时在我的个人资料屏幕上返回错误的代码行:

import SwiftUI
import SDWebImageSwiftUI


struct AccountViewNew: View {
    
    
    
    @EnvironmentObject var session: SessionStore
    
    func getUser() {
        
        session.listen()
    }
    
    var user: User?
    var body: some View {
       
      
                    VStack (alignment: .leading){
                        HStack {
                            Text(user?.firstname ?? "Change")
                                .font(.system(size: 20, weight: .bold, design: .default))
                                .foregroundColor(Color.white)
                                .multilineTextAlignment(.leading)
                            
                            Text(user?.lastname ?? "Your Name")
                                .font(.system(size: 20, weight: .bold, design: .default))
                                .foregroundColor(Color.white)
                                .multilineTextAlignment(.leading)
                        } 
                        .onAppear(perform: getUser)
4

0 回答 0