Фильтровать данные Firebase SwiftUI - PullRequest
0 голосов
/ 24 апреля 2020

Этот код добавляет все данные в один массив. В HomeViev я использую Foreach и добавляю данные в список. Но я должен разделить данные на две части. Коллекция состояния имеет два типа «активный» и «закрытый», но я не знаю, как я могу фильтровать

import SwiftUI
import Combine
import Firebase

let dbCollection = Firestore.firestore().collection("Signals")

class FirebaseSession : ObservableObject {

    @Published var session: User? { didSet { self.didChange.send(self) }}
    @Published var data = [Signal]()

    var didChange = PassthroughSubject<FirebaseSession, Never>()
    var handle: AuthStateDidChangeListenerHandle?


    func listen () {
        handle = Auth.auth().addStateDidChangeListener { (auth, user) in
            if let user = user {
                print("Got user: \(user)")
                self.session = User(uid: user.uid, email: user.email)
                self.readData()
            } else {
                self.session = nil
            }
        }
    }

    func readData() {
        dbCollection.addSnapshotListener { (documentSnapshot, err) in
            if err != nil {
                print((err?.localizedDescription)!)
                return
            }else {
                print("read data success")
            }

            documentSnapshot!.documentChanges.forEach { i in

// Считывать созданные в реальном времени данные с сервера

            if i.type == .added {
                let id = i.document.documentID
                let symbol = i.document.get("symbol") as? String ?? ""
                let status = i.document.get("status") as? String ?? ""
                self.data.append(Signal(id: id, symbol: symbol, status: status))
            }

/ / Чтение данных в реальном времени с сервера

            if i.type == .modified {
                self.data = self.data.map { (eachData) -> Signal in
                    var data = eachData
                    if data.id == i.document.documentID {
                        data.symbol = i.document.get("symbol") as! String
                        data.status = i.document.get("status") as? String ?? ""
                        return data
                    }else {
                        return eachData
                    }
                }
            }

// Когда данные удаляются ...

            if i.type == .removed {
                let id = i.document.documentID
                for i in 0..<self.data.count{
                    if self.data[i].id == id{
                        self.data.remove(at: i)
                        return
                    }
                }
            }
        }
    }
}

}

1 Ответ

1 голос
/ 24 апреля 2020

Вопрос гласит:

Но я должен разделить данные на два

Я предполагаю, что это означает два массива; один для активного и один для закрытого.

var activeData = [...
var closedData = [...

Есть несколько способов сделать это

1) Запросить Firestore для всех полей состояния, равных активному, и загрузить эти документы в активный массив, а затем другой запрос для полей состояния, равных закрытым, и загрузите их в закрытом массиве

2) Я бы предложил более простой подход

if i.type == .added {
   let id = i.document.documentID
   let symbol = i.document.get("symbol") as? String ?? ""
   let status = i.document.get("status") as? String ?? ""

   if status == "active" {
      self.activeData.append(Signal(id: id, symbol: symbol, status: status))
   } else {
      self.closedData.append(Signal(id: id, symbol: symbol, status: status))
   }
}

и сделал бы то же самое в .modified и .removed; определить статус, чтобы код знал, из какого массива его удалить.

РЕДАКТИРОВАТЬ:

На основе комментария

Я не знаю, как запросить это коды.

Я предоставляю код для запроса сигналов, которые активны . Этот код будет возвращать только активные сигналы, и когда сигналы станут активными, неактивными и т. Д. c, это изменит signalArray , чтобы он оставался в синхронизации c с данными.

let dbCollection = Firestore.firestore().collection("Signals")
let query = dbCollection.whereField("status", isEqualTo: "active").addSnapshotListener( { querySnapshot, error in
    guard let snapshot = querySnapshot else {
        print("Error fetching snapshots: \(error!)")
        return
    }

    snapshot.documentChanges.forEach { diff in
        if (diff.type == .added) {
            let signalToAdd = Signal(withDoc: diff.document)
            self.signalArray.append(signalToAdd)
        }
        if (diff.type == .modified) {
            let docId = diff.document.documentID
            if let indexOfSignalToModify = self.signalArray.firstIndex(where: { $0.signal_id == docId} ) {
                let signalToModify = self.signalArray[indexOfSignalToModify]
                signalToModify.updateProperties(withDoc: diff.document)
            }
        }
        if (diff.type == .removed) {
            let docId = diff.document.documentID
            if let indexOfSignalToRemove = self.signalArray.firstIndex(where: { $0.signal_id == docId} ) {
                self.signalArray.remove(at: indexOfSignalToRemove)
            }
        }
    }
})

Обратите внимание, что мой класс сигналов имеет инициализатор, который принимает QueryDocumentSnapshot для его инициализации, а также функцию .updateProperties для обновления его внутренних свойств.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...