无法将从 Firebase 获取的数据添加到新数组
Posted
技术标签:
【中文标题】无法将从 Firebase 获取的数据添加到新数组【英文标题】:Can't add data fetched from Firebase to new Array 【发布时间】:2021-09-13 15:43:38 【问题描述】:我正在从 3 个不同的集合中获取来自 firebase 的数据。获取数据后,我想将 3 个函数中的数据附加到 1 个新数组中,以便将所有数据存储在一个地方。但是,一旦我追加它就会变成空的,就像 fetch 函数不起作用一样。我已经测试和调试过,数据在那里,但我似乎无法将获取的数据添加到新数组中。
型号
import Foundation
import SwiftUI
struct GameModel: Identifiable
var id = UUID()
var title: String
var descriptionMenu: String
var imageNameMenu: String
Fetch Data Class
import Foundation
import SwiftUI
import Firebase
class SearchController: ObservableObject
@Published var allGames = [GameModel]()
@Published var cardsMenu = [GameModel]()
@Published var diceMenu = [GameModel]()
@Published var miscellaneuosMenu = [GameModel]()
private var db = Firestore.firestore()
func fetchCardGamesData() ...
func fetchDiceGamesData() ...
func fetchMiscGamesData() ...
func combineGames()
for i in cardsMenu
allGames.append(i)
for n in diceMenu
allGames.append(n)
for x in miscellaneuosMenu
allGames.append(x)
Fetch data Functions
func fetchCardGamesData()
db.collection("cardsMenu").addSnapshotListener (querySnapshot, error) in
guard let documents = querySnapshot?.documents else
print("No documents")
return
self.cardsMenu = documents.map (queryDocumentSnapshot) -> GameModel in
let data = queryDocumentSnapshot.data()
let title = data["title"] as? String ?? ""
let descriptionMenuRecieved = data["descriptionMenu"] as? String ?? ""
let descriptionMenu = descriptionMenuRecieved.replacingOccurrences(of: "\\n", with: "\n")
let imageNameMenu = data["imageNameMenu"] as? String ?? ""
let allGameInfo = GameModel(title: title, descriptionMenu: descriptionMenu, imageNameMenu: imageNameMenu)
return allGameInfo
func fetchDiceGamesData()
db.collection("diceMenu").addSnapshotListener (querySnapshot, error) in
guard let documents = querySnapshot?.documents else
print("No documents")
return
self.diceMenu = documents.map (queryDocumentSnapshot) -> GameModel in
let data = queryDocumentSnapshot.data()
let title = data["title"] as? String ?? ""
let descriptionMenuRecieved = data["descriptionMenu"] as? String ?? ""
let descriptionMenu = descriptionMenuRecieved.replacingOccurrences(of: "\\n", with: "\n")
let imageNameMenu = data["imageNameMenu"] as? String ?? ""
let allGameInfo = GameModel(title: title, descriptionMenu: descriptionMenu, imageNameMenu: imageNameMenu)
return allGameInfo
func fetchMiscGamesData()
db.collection("miscellaneuosMenu").addSnapshotListener (querySnapshot, error) in
guard let documents = querySnapshot?.documents else
print("No documents")
return
self.miscellaneuosMenu = documents.map (queryDocumentSnapshot) -> GameModel in
let data = queryDocumentSnapshot.data()
let title = data["title"] as? String ?? ""
let descriptionMenuRecieved = data["descriptionMenu"] as? String ?? ""
let descriptionMenu = descriptionMenuRecieved.replacingOccurrences(of: "\\n", with: "\n")
let imageNameMenu = data["imageNameMenu"] as? String ?? ""
let miscellaneousGames = GameModel(title: title, descriptionMenu: descriptionMenu, imageNameMenu: imageNameMenu)
return miscellaneousGames
View
import SwiftUI
import Foundation
struct SearchView: View
@ObservedObject var allGames = SearchController()
var body: some View
NavigationView
ZStack(alignment: .top)
GeometryReader_ in
//Text("Home")
.background(Color("Color").edgesIgnoringSafeArea(.all))
SearchBar(data: self.$allGames.allGames)
.padding(.top)
.navigationBarTitle("Search")
.padding(.top, -20)
.onAppear()
self.allGames.fetchCardGamesData()
self.allGames.fetchDiceGamesData()
self.allGames.fetchMiscGamesData()
self.allGames.combineGames()
.navigationViewStyle(StackNavigationViewStyle())
.listStyle(PlainListStyle())
搜索栏
struct SearchBar: View
@State var txt = ""
@Binding var data: [GameModel]
var body: some View
VStack(spacing: 0)
HStack
TextField("Search", text: self.$txt)
if self.txt != ""
Button(action:
self.txt = ""
, label:
Image(systemName: "xmark.circle.fill")
)
.foregroundColor(.gray)
.padding()
if self.txt != ""
if self.data.filter($0.title.lowercased().contains(self.txt.lowercased())).count == 0
Text("No Results Found")
.foregroundColor(Color.black.opacity(0.5))
.padding()
else
List(self.data.filter$0.title.lowercased().contains(self.txt.lowercased()))
i in
NavigationLink(destination: i.view.navigationBarTitleDisplayMode(.inline).onAppear()
// Clear searchfield when return
txt = ""
)
Text(i.title)
.frame(height: UIScreen.main.bounds.height / 3)
.padding(.trailing)
.background(Color.white)
.cornerRadius(10)
.padding()
希望你们能帮助我。
【问题讨论】:
【参考方案1】:您的所有fetchCardGamesData
、fetchDiceGamesData
和fetchMiscGamesData
函数都包含异步请求。这意味着当你调用combineGames
时,它们都没有完成,所以你只是在追加空数组。
在您的情况下,最简单的方法可能是将allGames
设为计算属性。然后,每当其他@Published
属性之一在其fetch
方法之后更新时,计算的属性将被重新计算并在您的SearchBar
中表示:
class SearchController: ObservableObject
@Published var cardsMenu = [GameModel]()
@Published var diceMenu = [GameModel]()
@Published var miscellaneuosMenu = [GameModel]()
var allGames: [GameModel]
cardsMenu + diceMenu + miscellaneuosMenu
请注意,不再有 combineGames
函数,因此您不会再调用它了。
【讨论】:
我已添加计算属性,但在 SearchView 中出现错误“无法分配给属性:'allGames' 是仅获取属性”。如何从 SearchController 获取数据到 SeachView 以到达 SearchBar 由于您没有包含SearchBar
,我没有意识到它需要对allGames
的写入权限。通常在搜索栏中,您根据搜索条件过滤数据。也许这就是你应该做的?如果没有,我可以提供不同的解决方案,但是根据正在搜索的内容来改变 allGames
似乎很有趣......
对不起,我忘了。我现在在帖子中添加了 SearchBar。
你永远不会变异data
。只需删除声明前的@Binding
,不要在调用现场使用$
:SearchBar(data: self.allGames.allGames)
好吧,我很想看到你接受。我对 Swift 和 SwitUI 还很陌生,所以我还在边学习边学习。以上是关于无法将从 Firebase 获取的数据添加到新数组的主要内容,如果未能解决你的问题,请参考以下文章
如何从 Firebase 推送/获取数据并使用 Java 添加到二维数组?
Android Studio Firebase Firestore 无法检索字段数据