SwiftUI + Firestore - 基于从 Firestore 返回的数组的过滤器列表

Posted

技术标签:

【中文标题】SwiftUI + Firestore - 基于从 Firestore 返回的数组的过滤器列表【英文标题】:SwiftUI + Firestore - Filter List based on array returned from Firestore 【发布时间】:2020-01-05 18:34:00 【问题描述】:

我正在尝试获取 Firestore 子集合查询的结果,然后根据查询结果过滤项目列表。

我能够成功查询和打印以控制台我的 Firestore 查询,但是,我对如何将查询结果设置为可以过滤列表的数组有点迷茫。

在我的函数中打印 favoriteID 的值显示:

“[163, 169]”

我正在努力解决如何将该数组附加到“self.data.append...”中,然后根据“data”的值在我的视图中过滤列表。

这是我当前的代码。它目前只显示我的数据模型中的所有项目。我希望它过滤并仅显示具有匹配产品 ID 的项目。

import SwiftUI
import Firebase
import FirebaseFirestore

struct FavoritesView: View 
@EnvironmentObject var session: SessionStore
@Environment(\.presentationMode) var presentationMode: Binding<PresentationMode>
@State var data: [FavoritesStore] = []

var model = Passport.all()
let db = Firestore.firestore()

func getFavorites() 
    let userID = Auth.auth().currentUser?.uid ?? "nil"

    if (session.session != nil) 
        self.data.removeAll()
        db.collection("users").document(userID).getDocument  (document, error) in
            if let document = document, document.exists 
                let favoriteID = document.get("favorites") as! Array<Int>
               print(favoriteID as Any)
            //  self.data.append(FavoritesStore(favorites: favoriteID) as! Array<Any>)
           //     print(self.data)
                 else 
                    print("Document does not exist")
                    
                
        


var body: some View 
    ZStack 
        VStack 
            List 
                ForEach(self.model)  venues in
                    ForEach(venues.venues)  items in
                        ForEach(items.venueItems)  item in
                            VStack 
                                Text(item.title)
                            
                        

                    
                
            
            .listStyle(GroupedListStyle())
            .navigationBarTitle(Text(""))
            .resignKeyboardOnDragGesture()
            .background(Color("bodyBackground"))
            .onAppear(perform: getFavorites)
        
        VStack 
            GeometryReader  gr in
                HStack 
                    Button(action: self.presentationMode.wrappedValue.dismiss()) 
                        Image(systemName: "chevron.left")
                            .foregroundColor(.black)
                            .padding(.leading, 16)
                        HStack 
                            Text("Explore · Favorites")
                                .font(.system(size: 15))
                                .fontWeight(.bold)
                                .foregroundColor(Color.black)

                                .padding()
                            Spacer()
                        
                    .frame(width: gr.size.width * 0.92, height: 48)
                        .background(Color.white)
                        .cornerRadius(8)
                        .shadow(color: Color("Shadow"), radius: 10, x: 2, y: 7)
                .padding(.leading, 16)
                Spacer()
            
        
        .padding(.top, 50)
        .edgesIgnoringSafeArea(.top)

        
    


class FavoritesStore: ObservableObject 
    @Published var favorites: [Favorite]

init (favorites: [Favorite]) 
    self.favorites = favorites
    



class Favorite: ObservableObject 
    var id: Int

    init(id: Int) 
        self.id = id
        

护照模型

Passport (
            id: 1001,
            passportPremium: false,
            passportActive: true,
            passportTitle : "Festival of the Holidays",
            passportDescription: "An International Yuletide Extravaganza Savor seasonal food & beverage specialties at the expanded Holiday Kitchens. And take a festive global tour—as costumed performers bring time-honored traditions to life throughout World Showcase!",
            passportDates: "Nov. 29 - Dec. 30, 2019",
            passportYear: "2019",
            passportImage: "Event-Festival-Holidays",
            passportImageVert: "Event-Festival-Holidays-Vert",
            venues: [
                Venue (
                    title: "Bavaria Holiday Kitchen",
                    venueImage: "defaultVenue",
                    venueDesc: "ipsum lorem",
                    venueArea: "World Showcase East",
                    coordinate: .init(latitude: -33.852222, longitude: 151.210556),
                    venueItems: [
                        venueItem (
                            id: 101,
                            title: "Potato Dumpling",
                            itemURL: "https://www.example.com/app/wdw-default.png",
                            productDescription: "Potato Dumpling with Mushroom Sauce",
                            productPrice: 4.50,
                            productType: "Food",
                            newStatus: false,
                            diningPlan: false,
                            kidFriendly: true,
                            vegetarian: false,
                            glutenFree: false,
                            featuredProduct: false,
                            containsAlcohol: false
                        ),
                        venueItem (
                            id: 102,
                            title: "Pork Schnitzel",
                            itemURL: "https://www.example.com/app/wdw-default.png",
                            productDescription: "Pork Schnitzel with Mushroom Sauce and Spaetzle",
                            productPrice: 6.25,
                            productType: "Food",
                            newStatus: true,
                            diningPlan: false,
                            kidFriendly: false,
                            vegetarian: false,
                            glutenFree: false,
                            featuredProduct: false,
                            containsAlcohol: false
                        ),
                        venueItem (
                            id: 103,
                            title: "Cheese Fondue",
                            itemURL: "https://www.example.com/app/wdw-default.png",
                            productDescription: "Cheese Fondue in a Bread Bowl with Fresh Steamed Baby Vegetables and Marble Potatoes",
                            productPrice: 8.25,
                            productType: "Food",
                            newStatus: false,
                            diningPlan: false,
                            kidFriendly: true,
                            vegetarian: false,
                            glutenFree: false,
                            featuredProduct: false,
                            containsAlcohol: false
                        ),

【问题讨论】:

【参考方案1】:

如果我理解正确,你可以尝试这样的事情

    for document in querySnapshot!.documents 
          print("\(document.documentID) => \(document.data())")
          let favoriteID = document.data("productID") as Int
          if let row = self.model.firstIndex(where:  $0.productID != favoriteID  ) 
              self.model.remove(at: row)
           
    

【讨论】:

我用数据模型更新了问题。我现在唯一遇到的问题是“if let row =”语法,因为 productID 是嵌套的。 ProductID 将引用“venueItem”上的“id” 您能否详细说明 ProductID 的问题所在?

以上是关于SwiftUI + Firestore - 基于从 Firestore 返回的数组的过滤器列表的主要内容,如果未能解决你的问题,请参考以下文章

SwiftUI UserDefaults 干扰 Firebase Firestore 数据

如何从firestore中检索swiftUI中的预定义项目列表?

swiftUI 中的选取器正在从 Firestore 中选择文档 ID 而不是文档字段

SwiftUI+Firestore 中的多选列表

SwiftUI Firebase Firestore 查询函数

SwiftUI Lists + Firebase Firestore,获取数据然后取消获取? (漏洞)