无法将从 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】:

您的所有fetchCardGamesDatafetchDiceGamesDatafetchMiscGamesData 函数都包含异步请求。这意味着当你调用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 无法检索字段数据

我无法从 firebase 操作存储在数组中的数据

渲染从 firebase firestore 获取的数组数据

将firebase数据添加到ios swift中的数组

如何将从firebase存储上传的图像保存到firestore数据库中的currentUser