【问题标题】:Display name for Firebase User returns an empty String in SwiftUI ViewFirebase 用户的显示名称在 SwiftUI 视图中返回一个空字符串
【发布时间】:2020-12-24 23:26:12
【问题描述】:

我正在使用 SwiftUI 和 Firebase 制作一个送餐应用程序,并且我已经能够实现电子邮件/密码身份验证。我有一个 ProfileView 来显示用户名和他们拥有的供应商。但是,当我尝试访问用户的 displayName 属性时,它只返回一个空字符串。有什么方法可以从 Firebase 控制台访问或更改用户的显示名称。

ProfileView.swift

struct ProfileView: View {
    var user: User?
    @ObservedObject var vendorRepo = VendorRepository()
    
    var body: some View {
        VStack(alignment: .center) {
            Text("Profile")
                .font(.largeTitle)
                .bold()
            
            ImageView(imageName: "examplePP", width: 100, height: 100)
            
            Text(user?.displayName ?? "No Username Provided")
                .font(.title)
            
            Divider()
            
            NavigationView {
                List(vendorRepo.userOwnedVendors) { vendor in
                    NavigationLink(destination: VendorView(vendor: vendor)) {
                        VendorRow(vendor: vendor)
                    }
                }
                .navigationBarTitle(Text("Vendors Owned by You"), displayMode: .inline)
            }
        }
        .padding(.top, -25.0)
        .onAppear() {
            self.vendorRepo.readUserOwnedVendors()
        }
    }
}

EmailSignUpView.swift

struct EmailSignUpView: View {
    @State var displayName: String = ""
    @State var email: String = ""
    @State var password: String = ""
    
    var body: some View {
        VStack(alignment: .center, spacing: 20) {
            VStack {
                Text("Sign Up with Email")
                    .font(.largeTitle)
                    .bold()
                
                Text("You must have an account to be able to start a vendor or modify your existing ones. If you already have an account, go to the Login Page.")
                    .multilineTextAlignment(.center)
            }
            
            Spacer()
            
            VStack(alignment: .center) {
                Text("Enter your Display Name:")
                TextField("Display Name", text: $displayName)
                    .disableAutocorrection(true)
                    .autocapitalization(.none)
                    .multilineTextAlignment(.center)
            }
            
            VStack(alignment: .center) {
                Text("Enter your Email:")
                TextField("Email Address", text: $email)
                    .disableAutocorrection(true)
                    .autocapitalization(.none)
                    .multilineTextAlignment(.center)
            }
            
            VStack(alignment: .center) {
                Text("Enter your Password:")
                SecureField("Password", text: $password)
                    .disableAutocorrection(true)
                    .autocapitalization(.none)
                    .multilineTextAlignment(.center)
            }
            
            Spacer()

            Button(action: createAccount) {
                Text("Sign Up")
                    .font(.title)
            }
            
            Spacer()
        }
        .padding(.horizontal)
    }
    
    func createAccount() {
        Auth.auth().createUser(withEmail: self.email, password: self.password, completion: {result, error in
            var contentTitleString: String = ""
            var contentSubtitleString: String = ""
            
            if let error = error {
                print(error)
                contentTitleString = "Sign Up Failed!"
                contentSubtitleString = error.localizedDescription
                self.password = ""
            } else {
                print("\(self.email) has been signed up!")
                contentTitleString = "Sign Up Successful!"
                contentSubtitleString = "Please restart the app for changes to take place"
                self.displayName = ""
                self.email = ""
                self.password = ""
                if let currentUser = Auth.auth().currentUser?.createProfileChangeRequest() {
                    currentUser.displayName = self.displayName
                    currentUser.commitChanges(completion: {error in
                        if let error = error {
                            print(error)
                        } else {
                            print("DisplayName changed")
                        }
                    })
                }
            }
            
            let content = UNMutableNotificationContent()
            content.title = contentTitleString
            content.subtitle = contentSubtitleString
            content.sound = .default

            // show this notification one seconds from now
            let trigger = UNTimeIntervalNotificationTrigger(timeInterval: 0.1, repeats: false)
            let request = UNNotificationRequest(identifier: UUID().uuidString, content: content, trigger: trigger)
            
            UNUserNotificationCenter.current().add(request)
        })
    }
}

当我调用 ProfileView 视图时,我将 Auth.auth().currentUser 传递给 user 属性。

【问题讨论】:

  • 您能确认用户在 ProfileView 启动时已登录吗?我怀疑没有用户登录,并且 currentUser == nil,所以 displayName == nil,并返回“”。
  • @TahmidAzam 访问 ProfileView 的按钮只有在用户登录时才能访问。而且我还可以看到我拥有的供应商。
  • 更改createAccount 中的显示名称有效吗?

标签: swift xcode firebase swiftui


【解决方案1】:

我想我发现了错误。在 EmailSignUpView 的 createAcount() 函数中:

func createAccount() {
        Auth.auth().createUser(withEmail: self.email, password: self.password, completion: {result, error in
            var contentTitleString: String = ""
            var contentSubtitleString: String = ""
            
            if let error = error {
                print(error)
                contentTitleString = "Sign Up Failed!"
                contentSubtitleString = error.localizedDescription
                self.password = ""
            } else {
                print("\(self.email) has been signed up!")
                contentTitleString = "Sign Up Successful!"
                contentSubtitleString = "Please restart the app for changes to take place"
                self.displayName = ""
                self.email = ""
                self.password = ""
                if let currentUser = Auth.auth().currentUser?.createProfileChangeRequest() {
                    currentUser.displayName = self.displayName
                    currentUser.commitChanges(completion: {error in
                        if let error = error {
                            print(error)
                        } else {
                            print("DisplayName changed")
                        }
                    })
                }
            }
            
            let content = UNMutableNotificationContent()
            content.title = contentTitleString
            content.subtitle = contentSubtitleString
            content.sound = .default

            // show this notification one seconds from now
            let trigger = UNTimeIntervalNotificationTrigger(timeInterval: 0.1, repeats: false)
            let request = UNNotificationRequest(identifier: UUID().uuidString, content: content, trigger: trigger)
            
            UNUserNotificationCenter.current().add(request)
        })
    }

我在更新前将 displayName 设置为 ""。糟糕!

【讨论】:

  • 是的,我也是在将它复制到本地项目后才发现的......
  • 另外,您无需传递用户对象。实施 Firebase 时,您可以在项目中的任何位置调用它。例如我会将此 Text(user?.displayName ?? "No Username Provided") 更改为 Text(Auth.auth().currentUser?.displayName ?? "No Username Provided")
猜你喜欢
  • 2020-07-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-10-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多