如何在结构中正确显示来自 Firestore 的数据?
Posted
技术标签:
【中文标题】如何在结构中正确显示来自 Firestore 的数据?【英文标题】:How to display data from Firestore at struct correctly? 【发布时间】:2021-05-22 05:11:47 【问题描述】:我目前正在使用SwiftUI
和Firebase
(FirebaseFirestoreSwift
) 开发一个应用程序。
显示View
时,想从Firestore
获取数据并显示,但显示的数据不正确。
在下面视图的屏幕上,如果我输入一个标题并点击[添加],我希望输入的内容会保存在FireStore
Collection
中,然后Documents
中的所有Documents
@ 将被获取并显示。
但它不能很好地工作。
例如,如果我输入如下数据:
-
输入“AAA”并点击[添加]按钮→将显示AAA
输入“BBB”并点击[添加]按钮→将显示BBB
输入“CCC”并点击[添加]按钮→将显示BBB
然后,如果我在Firebase
控制台上检查数据,我可以确认它已保存为您输入的内容(AAA、BBB、CCC)。
我该如何解决这个问题?
代码如下:
import SwiftUI
import Firebase
import FirebaseFirestoreSwift
struct GetDataTest: View
@State var items:[Item] = []
@State var title:String = ""
var body: some View
VStack
List
ForEach(self.items.indices, id: \.self)index in
ListRowTest(
title:self.items[index].title
)
// Text(self.items[index].title)
// .font(.title)
// .fontWeight(.bold)
Button(action:
self.getAllItems()
, label:
Text("Update")
)
TextField("Enter titel",text:self.$title)
.textFieldStyle(RoundedBorderTextFieldStyle())
Button(action:
let item = Item(title: self.title)
self.addItem(item: item) (status) in
self.getAllItems()
self.title = ""
, label:
Text("Add")
)
.onAppear
self.getAllItems()
func getAllItems()
self.items = []
let ref = Firestore.firestore()
ref.collection("Items").getDocuments
(snap, err) in
guard let docs = snap elsereturn
docs.documentChanges.forEach (doc) in
let item = try! doc.document.data(as:Item.self)
self.items.append(item!)
func addItem(item:Item , completion:@escaping (Bool) -> ())
let ref = Firestore.firestore()
do
let _ = try
ref.collection("Items").addDocument(from: item) (error) in
if error != nil
completion(false)
return
completion(true)
catch
print(error.localizedDescription)
completion(false)
struct ListRowTest: View
@State var title:String
var body: some View
HStack
Text(title)
.font(.title)
.fontWeight(.bold)
struct Item : Identifiable,Codable
@DocumentID var id : String?
var title : String
enum CodingKeys : String,CodingKey
case id
case title
ListRowTest(
title:self.items[index].title
)
如果我将上面的代码更改如下,它将正确显示。 但是我想用struct作为组件,所以这个方法解决不了。
Text(self.items[index].title)
.font(.title)
.fontWeight(.bold)
Xcode:版本 12.3
ios:14.0
生命周期:SwiftUI 应用
【问题讨论】:
【参考方案1】:使用 Firebase/Firestore 确实是在处理异步函数。 所以我会重组你的代码以使用封装的 ObservableObject 项目和数据库调用,例如这样的:
class ItemsModel: ObservableObject
@Published var items = [Item]()
private var ref = Firestore.firestore()
func getAllItems()
ref.collection("Items").getDocuments (snap, err) in
guard let docs = snap elsereturn
docs.documentChanges.forEach (doc) in
let item = try! doc.document.data(as:Item.self)
self.items.append(item!)
func addItem(item: Item, completion:@escaping (Bool) -> ())
do
let _ = try
ref.collection("Items").addDocument(from: item) (error) in
if error != nil
completion(false)
return
self.items.append(item!) // <----
completion(true)
catch
print(error.localizedDescription)
completion(false)
struct GetDataTest: View
@ObservedObject private var itemsModel = ItemsModel() // <----
@State var title:String = ""
var body: some View
VStack
List
ForEach(itemsModel.items.indices, id: \.self) index in
ListRowTest(title: itemsModel.items[index].title)
Button(action:
itemsModel.getAllItems()
, label:
Text("Update")
)
TextField("Enter titel",text:self.$title).textFieldStyle(RoundedBorderTextFieldStyle())
Button(action:
let item = Item(title: self.title)
itemsModel.addItem(item: item) error in
// deal with error here
self.title = ""
, label:
Text("Add")
)
.onAppear
itemsModel.getAllItems()
【讨论】:
以上是关于如何在结构中正确显示来自 Firestore 的数据?的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Android 的 RecyclerView 中显示来自 Firestore 的数据?
如何在网站中显示来自 Firestore 下载 URL 的图像
Java Firestore Android 在查询中使用数组列表来显示来自关注用户的帖子