Reputation: 25
This code adds all the data in a single array. In HomeViev I use to Foreach and I added to data to list. But I have to split the data in two. status collection has two type "active" and "closed" but I don't know how can I filter
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
// Read real time created data from server
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))
}
// Read real time modify data from server
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
}
}
}
// When data is removed...
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
}
}
}
}
}
}
}
Upvotes: 0
Views: 1097
Reputation: 35648
The question states
But I have to split the data in two
I assume that means two arrays; one for active and one for closed.
var activeData = [...
var closedData = [...
There are a couple of ways to do that
1) Query Firestore for all status fields equal to active and load those documents into the active array and then another query for status fields equal closed and load those in the the closed array
2) I would suggest a simpler approach
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))
}
}
and do the same thing within .modified and .removed; identify the status so the code will know which array to remove it from.
EDIT:
Based on a comment
I don't know how to query this codes.
I am providing code to query for signals that are active. This code will return only active signals and as signals become active, inactive etc, this will modify a signalArray to stay in sync with the data.
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)
}
}
}
})
Note that my Signal Class has an initializer that accepts a QueryDocumentSnapshot to initialize it as well as a .updateProperties function to update its internal properties.
Upvotes: 2