[英]Get data from Firestore with SwiftUI
我有一个 class,我从 Firebase 获取数据。 但是我不能完全按照我的意愿得到它,例如 document("abc") 这里我需要从另一个地方获取名称“abc”,每次点击可能会出现不同的名称。
我无法将其分配给我从中获取数据的 class,您能帮帮我吗?
import SwiftUI
import Firebase
struct StadiumNameView: View {
var body: some View {
VStack{
List(stadiumnameeeee) { i in
NavigationLink(destination: SelectedStadiumView(selectedStadium:i.name)){
Text(i.name)
}
}
}
}
}
struct StadiumNameView_Previews: PreviewProvider {
static var previews: some View {
StadiumNameView()
}
}
我需要将此处的“i.name”传递给以下 class。
import SwiftUI
import Firebase
class UserInfoModel : ObservableObject {
@Published var city=""
@Published var email=""
@Published var name=""
@Published var surname=""
@Published var phone=""
@Published var town=""
@Published var type=""
@Published var id=""
@Published var birthday=""
@Published var favStadium=[String]()
init(){
let db=Firestore.firestore()
db.collection("Users").document(Auth.auth().currentUser!.uid).addSnapshotListener { (snapshot, error) in
if error == nil {
if let city=snapshot?.get("City") as? String {
self.city=city
}
if let email=snapshot?.get("Email") as? String {
self.email=email
}
if let name=snapshot?.get("Name") as? String {
self.name=name
}
if let surname=snapshot?.get("Surname") as? String {
self.surname=surname
}
if let phonenumber=snapshot?.get("Phone") as? String {
self.phone=phonenumber
}
if let town=snapshot?.get("Town") as? String {
self.town=town
}
if let type=snapshot?.get("Type") as? String {
self.type=type
}
if let id=snapshot?.get("User") as? String {
self.id=id
}
if let birthday=snapshot?.get("DateofBirth") as? String {
self.birthday=birthday
}
if let favStadiums=snapshot?.get("FavoriteStadiums") as? [String]{
self.favStadium=favStadiums
}
}
}
}
}
而不是使用 class,您应该 model 将您的数据对象作为结构,然后实现一个包含这些结构集合的视图 model。
此外,考虑使用 Codable 而不是手动映射数据。
这是您的代码的更新版本:
import SwiftUI
// import Firebase --> No need to import Firebase in the view
struct StadiumNameView: View {
@StateObject userViewModel: UserViewModel()
var body: some View {
VStack {
List(userViewModel.users) { user in
Text(user.name)
}
}
}
}
struct StadiumNameView_Previews: PreviewProvider {
static var previews: some View {
StadiumNameView()
}
}
import Firebase
struct UserInfoModel: Codable, Identifiable {
@DocumentID var id: String?
var city = ""
var email = ""
var name = ""
var surname = ""
var phone = ""
var town = ""
var type = ""
var id = ""
var birthday = ""
var favStadium = [String]()
}
class UserViewModel: ObservableObject {
@Published var users = [UserInfoModel]()
@Published var errorMessage: String?
private var db = Firestore.firestore()
private var listenerRegistration: ListenerRegistration?
public func unsubscribe() {
if listenerRegistration != nil {
listenerRegistration?.remove()
listenerRegistration = nil
}
}
func subscribe() {
if listenerRegistration == nil {
listenerRegistration = db.collection("users")
.addSnapshotListener { [weak self] (querySnapshot, error) in
guard let documents = querySnapshot?.documents else {
self?.errorMessage = "No documents in 'users' collection"
return
}
self?.users = documents.compactMap { queryDocumentSnapshot in
let result = Result { try queryDocumentSnapshot.data(as: UserInfoModel.self) }
switch result {
case .success(let userInfo):
if let userInfo = userInfo {
// A UserInfoModel value was successfully initialized from the DocumentSnapshot.
self?.errorMessage = nil
return userInfo
}
else {
// A nil value was successfully initialized from the DocumentSnapshot,
// or the DocumentSnapshot was nil.
self?.errorMessage = "Document doesn't exist."
return nil
}
case .failure(let error):
// A UserInfo value could not be initialized from the DocumentSnapshot.
switch error {
case DecodingError.typeMismatch(_, let context):
self?.errorMessage = "\(error.localizedDescription): \(context.debugDescription)"
case DecodingError.valueNotFound(_, let context):
self?.errorMessage = "\(error.localizedDescription): \(context.debugDescription)"
case DecodingError.keyNotFound(_, let context):
self?.errorMessage = "\(error.localizedDescription): \(context.debugDescription)"
case DecodingError.dataCorrupted(let key):
self?.errorMessage = "\(error.localizedDescription): \(key)"
default:
self?.errorMessage = "Error decoding document: \(error.localizedDescription)"
}
return nil
}
}
}
}
}
}
有关如何使用 Codable 的更多详细信息,请查看我的文章Mapping Firestore Data in Swift - 综合指南。 GitHub 上也提供了所有代码: peterfriese/Swift-Firestore-Guide:在 Swift 中使用 Cloud Firestore 的综合指南。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.