How to Filter Firebase Data in Swift

How to filter Firebase data in Swift?

You have a few small mistakes in there. Overall nothing too bad, but combined they'll never work:

  1. calling any of the query... methods returns a new object
  2. you need to orderByChild() before you can filter on its value
  3. you need to loop over the results

Combining these:

let ref = FIRDatabase.database().referenceFromURL(FIREBASE_URL).child("topics")
let query = ref.queryOrderedByChild("published").queryEqualToValue(true)
query.observeEventType(.Value, withBlock: { (snapshot) in
for childSnapshot in snapshot.children {
print(childSnapshot)
}
})

We get this question regularly. For example, this from yesterday looks very similar: Firebase Query not Executing Properly. Since my explanation varies with every answer, I recommend browsing a bit to read my relevant answers until it clicks.

Filter Firebase Data SwiftUI

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.

Filtering data snapshot Swift Firebase

To load only the posts for a specific user, you'll want to use a Firebase query:

let uid = Auth.auth().currentUser.uid
let posts = Database.database().reference().child("user_posts")
let query = posts.queryOrdered(byChild: "").queryEqual(toValue: uid)
query.observe(.childAdded) {(snapshot: DataSnapshot) in
...

Also see the Firebase documentation on ordering and filtering data.

Firebase query on multiple filters in Swift

The code you show shouldn't event compile. Firebase Database queries can only contain a single orderBy... clause, and can never do suffix matching (your _NCAA is at the end of the key).

To allow you use-case you should have a key/property that consists of the week number, and the org (NCAA/NFL) value. E.g.

Games
--- 20190220000_NCAA (SportID)
--- WeekId : 1
--- WeekOrg : "01_NCAA"
--- etc...
--- 20190221000_NCAA
--- WeekId : 2
--- WeekOrg : "02_NCAA"
--- etc...
--- 20190204000_NFL
--- WeekId : 1
--- WeekOrg : "01_NFL"
--- etc...
--- etc...(SportsID)

With this in place you can get the nodes in week 1 for the NCAA with:

gamesRef.queryOrdered(byChild: "WeekOrg").queryEqual(toValue: "01_NCAA").observe(.value, with: { snapshot in

Also see my answer here: http://stackoverflow.com/questions/26700924/query-based-on-multiple-where-clauses-in-firebase



Related Topics



Leave a reply



Submit