我要做什么::我想在用户登录应用后在“个人资料”视图上显示用户的姓名。目前,我已经使用Firebase Auth实施了登录。用户创建帐户时,会在Firestore的“用户”集合中创建一条记录,该记录记录名字和姓氏以及电子邮件地址。
我尝试过的事情:在“个人资料”视图上,我当前具有一个“ getUser”功能,用于检查用户是否已登录,然后匹配该用户的Firebase Auth电子邮件地址并对其进行匹配到Firestore中的记录。之所以有效,是因为我已经通过控制台中记录的内容检查了查询返回的信息。但是,我不知道如何获取“ fName”信息并将其显示在视图的正文中。
这是数据库结构和我当前代码的屏幕截图。
import SwiftUI
import Firebase
import Combine
import FirebaseFirestore
struct ProfileView: View {
@EnvironmentObject var session: SessionStore
let db = Firestore.firestore()
func getUser() {
session.listen()
let query = db.collection("users").whereField("email", isEqualTo: session.session!.email!)
query.getDocuments { (QuerySnapshot, err) in
if let docs = QuerySnapshot?.documents {
for docSnapshot in docs {
print (docSnapshot.data())
}
}
}
}
var body: some View {
Group {
if (session.session != nil) {
NavigationView {
VStack {
Text("Welcome back \(session.session!.email ?? "user")")
Spacer()
Button(action: session.signOut) {
Text("Sign Out")
}.padding(.bottom, 60)
}
} // end NavigationView
} else {
AuthView()
}
}.onAppear(perform: getUser)
}
}
答案 0 :(得分:0)
我想您应该使用UserDefaults保存从Firestore返回的值
import UIKit
//your get user data logic here
let fName:String = <the first name retrieved from firestore>
// Get the standard UserDefaults as "defaults"
let defaults = UserDefaults.standard
// Save the String to the standard UserDefaults under the key, "first_name"
defaults.set(fName, forKey: "first_name")
并且在您的个人资料页面中,您应该获取该值
// you should have defaults initialized here
fnameToDisplay = defaults.string(forKey: "first_name")
答案 1 :(得分:0)
您好,我更喜欢制作一个ViewModel-NetworkManager类,它使ObservableObject
更加舒适,并且在其中可以获取和获取数据,并且当它们完成加载后,它们将更新视图。让我向您展示一个示例,它如何工作:
如您所见,我在其中创建了一个NetworkManager扩展ObservableObject(因为我想在用户完成加载时得到通知),您可以看到var user
带有@Published
的注释,使用户观察到的情况以及何时有新的数据集将通知视图进行更新。您还可以看到我在init上加载了数据,因此此类初始化的第一时间将调用fetchData()
func
class NetworkManager: ObservableObject {
let url: String = "https://jsonplaceholder.typicode.com/todos/1"
var objectWillChange = PassthroughSubject<NetworkManager, Never>()
init() {
fetchData()
}
@Published var user: User? {
didSet {
objectWillChange.send(self)
print("set user")
}
}
func fetchData() {
guard let url = URL(string: url) else {return}
print("fetch data")
URLSession.shared.dataTask(with: url) { (data, response, error) in
guard error == nil else {return}
print("no error")
guard let data = data else {return}
print("data is valid")
let user = try! JSONDecoder().decode(User.self, from: data)
DispatchQueue.main.async {
self.user = user
}
}.resume()
}
}
ContentView是我要放置用户数据或我声明的@ObservedObject var networkManager
的信息的地方,原因是它扩展了ObservableObject并放置了视图并传递了用户
struct ContentView: View {
@ObservedObject var networkManager = NetworkManager()
var body: some View {
VStack {
DetailsView(user: networkManager.user)
}
}
}
struct DetailsView: View {
var user: User?
var body: some View {
VStack {
Text("id: \(user?.id ?? 0)")
Text("UserID: \(user?.userId ?? 0 )")
Text("title: \(user?.title ?? "Empty")")
}
}
}
class User: Decodable, ObservableObject {
var userId: Int = 0
var id: Int = 0
var title: String = ""
var completed: Bool = false
}
PS:我没有正确解开物体,请考虑一下 您没有任何零例外