iOS Firebase get data where value equals to something - ios

How can I get data in swift3 from firebase where the value equals something.
In MySQL that would be "SELECT * FROM users WHERE type = 'brown'"; how can I write that where part in Firebase?
I have this DB
And I want to get all the data from it where month == currentMonth (I have a currentMonth variable)

You can Query like this:
let ref = Database.database().reference()
ref.child("Budget")
.queryOrdered(byChild: "Month")
.queryEqual(toValue: "November")
.observe(.value, with: { (snapshot: DataSnapshot) in
var array:[Budget] = []
for budgetChild in snapshot.children {
let budgetSnapshot = budgetChild as! DataSnapshot
let budgetDictionary = budgetSnapshot.value as! [String:String]
let budget: Budget = Budget()
budget.description_ = budgetDictionary["Description"]
budget.month = budgetDictionary["Month"]
budget.type = budgetDictionary["Type"]
budget.value = budgetDictionary["Value"]
array.append(budget)
}
})

As far as I'm aware firebase realtime database doesn't have support for querying like this. Instead you need to call down the whole ref 'budget' then filter it locally in your app.
FireStore apparently has better query support although its in Beta.

Related

ios firebase database get key of value

Sorry newbie here. I can't seem to find any solution that helps me get the following information from the firebase realtime database (see image)
orange rectangle marks structure of data and data to be retrieve
This is my current code
ref.child("locations").observe(.value, with: { snapshot in
for child in snapshot.children{
let valueD = child as! DataSnapshot
let keyD = valueD.key
let value1 = valueD.value
print(value1)
// This gives "-L-other letters" = 0 (but I only want the string without "= 0")
})
Is there any way I can do this? Thanks!
If locations is the root of what you show in the screenshot, you're only looping over the first level of children (37d42... etc). To get the keys you marked, you need to loop one level deeper. So:
ref.child("locations").observe(.value, with: { snapshot in
for child in snapshot.children{
for grandchild in child.children{
let valueD = grandchild as! DataSnapshot
let keyD = valueD.key
let value1 = valueD.value
print(keyD)
}
}
})

How to filter search in Firebase iOS

How can i filter a Firebase query on conditions. I have tried this code
let productsQuery = FIRDatabase.database().reference().child("Products").queryLimited(toFirst: 10)
//method 1
productsQuery.queryEqual(toValue: "Pending", childKey: "Status")
//method 2
productsQuery.queryOrdered(byChild: "Status").queryStarting(atValue: "Pending").queryEnding(atValue: "Pending")
But it always returns entire set which is huge (more than 10k entries)
I want to fetch only the objects in which "Status" = "Pending"
Backend shown here
I am sure such basic filtering would exist in Firebase. Please let me know.
You need to combine queryOrdered(byChild:) and queryEqual(toValue:) this way and use .observeEvent with it
let productsQuery = FIRDatabase.database().reference().child("Products")
productsQuery.queryOrdered(byChild: "Status").queryEqual(toValue:"Pending")
.queryLimited(toFirst: 10).observeSingleEvent(of: .value, with: { (snapshot : FIRDataSnapshot) in
})

Storing posts (image, caption) in Firebase database with auto increment Swift 3

I am trying to store user posts in my firebase data like the following:
I have successfully stored each image in storage with the following code:
let storage = FIRStorage.storage()
let data = UIImagePNGRepresentation(postImage!)
// guard for user id
guard let uid = FIRAuth.auth()?.currentUser?.uid else {
return
}
let photosRef = storage.reference().child("posts")
let imageName = NSUUID().uuidString
let photoRef = photosRef.child("\(uid)")
photoRef.child("\(imageName)").put(data!, metadata: nil){(metaData,error) in
if let error = error {
print("there was an error")
print(error.localizedDescription)
return
}else{
// store downloadURL
let downloadURL = metaData!.downloadURL()!.absoluteString
let values = ["uid": uid, "caption": caption, "download_url": downloadURL]
// store downloadURL at database
let databaseRef = FIRDatabase.database().reference()
// store values in posts/post_1 (post_1..post_2 etc)
}
}
However, I'm having trouble storing the downloadURL (values array) in my posts database because I can't figure out how to have an incremental value for post 1 post 2 post 3 etc etc
Is there a better way to store the posts in the posts database without needing incremental values?
Appreciate any help.
Thanks!
There are a number of ways to store incremental values - it all depends on how you want the values stored and how you will be retrieving and using them.
The general process is to create parent nodes using childByAutoId - Firebase generates the distinct node names for you.
let ref = rootNode.childByAutoid()
ref.setValue("my value")
This will result in nodes with a Firebase generated key
root_node
-Ynaosdokasodkpasd: "my Value"
That being said, it's hard to order them in a meaningful way, so you may want to add nodes that will enable you to specify the order
let ref = rootNode.childByAutoid()
let dict = ["text": "my value", timeStamp: "20161207131600"]
ref.setValue(dict)
which results in
-Ynaosdokasodkpasd
text: "my value"
timeStamp: "20161207131600"
you can then use the timeStamp to order your data in Firebase queries.

How can I find a specific Product id by sending Product Name?

I use Firebase For My Store App. I want to find a Product's Details by taking a product name for the user. My JSON format looks like this:
{
product :
electronic =
a = {
pname = "iphone 5"
pprice = "20000"
pdescription = "Details....." }
b = {
pname = "iphone 6"
pprice = "30000"
pdescription = "Details....." }
}
cloths =
a = pname = "shirt"
pprice = "200"
pdescription = "Details....." }
b = {
pname = "pents"
pprice = "300"
pdescription = "Details....." }
}
Now, suppose I have the name iphone 5, then how can I find out the other details of the product?
Try this :-
FIRDatabase.database().reference().child("product/electronic").queryOrderedByChild("pname").queryEqualToValue("iphone 5").observeSingleEventOfType(.Value , withBlock : {(snap) in
if let snapDict = snap.value as? [String:AnyObject]{
for each in snapDict{
print(each.0) // product key
print(each.1) //product details
}
}
})
import Firebase
FIRApp.configure()
ref = FIRDatabase.database().reference()
let prod_query = "iphone 5"
ref.observeSingleEventOfType(.Value, withBlock: { (snapshot) in
let product_enum = snapshot.children
while let product = product_enum.nextObject() as? FDataSnapshot {
product.queryEqualToValue(child:"\(prod_query)").observeSingleEventOfType(.Value, withBlock: { (snap) in
let pid = snap.key as! String
let pprice = snap.value!["pprice"] as! Int
let pdescription = snap.value!["pdescription"] as! String
})
}
})
This implies that you know what the product letter is so that you can pull the correct name, price, and description.
The while loop will iterate through the different types of products (electronics, cloths, etc) and perform a query searching for a product ID that contains the child with the pname you're looking for.
Firebase suggests that instead of using .Value, it's better to use .ChildAdded since it accomplishes the same goal while managing new objects added. But since it appears you are trying to view static data, .Value works just fine.
This should serve as an excellent example as to how you can retrieve data using Firebase. But I suggest checking out the documentation on your own just in case you have further questions.
While I really don't mind looking this information up... this site is used in order to gain a better understanding of code, rather than existing as a collection of personal assistants.
Showing research efforts within your question can go a long way.

Setting a class's values with multiple queries

I've got a class that has Title, users and a timestamp.
My database is set up like :
users
ablksjdlf39493
rooms
room1: true
rooms
room1
timestampOfLastPost: 39403942
users
039403fsjlkj: true
;alkjsdksdkj: true
I'm running a query on my user's rooms and grabbing the snapshot.key to get in this example "room1". Then inside of the first query I run another query and I use that key as a child reference to my rooms node to go to that room (rooms-->room1), and set is as my class object's title. From the 2nd query I'm pulling out the timestamp and use that for my object's timestamp.
I'm a bit confused how to get the childcount of out users.
I was running yet another nested query inside of my second query. But then I was getting all sorts of weird duplicate posts being added to my tableview when I was loading them. And that just doesn't seem very efficient anyways.
Is there a way in my second query to get both the timestamp and the children.count of my users node? The only way I've seen to do that is to run an observer on the specific node and do a snapshot.childrenCount.
edit:
currentUserFirebaseReference.child("rooms").observeEventType(.Value) { (snapshot: FIRDataSnapshot) in
self.interestsArray = []
if let snapshots = snapshot.children.allObjects as? [FIRDataSnapshot] {
for snap in snapshots {
let eachInterest = Interest()
let interestKey = snap.key
let title = snap.key.uppercaseString
eachInterest.title = title
//grabbing the user's current rooms and getting the snap.key to use for my next query.
DataService.ds.REF_INTERESTS.child(interestKey).observeEventType(.Value, withBlock: { (snapshot: FIRDataSnapshot) in
if let lastuser = snapshot.value!["lastJoin"] as? Int {
eachInterest.latestUser = lastuser
} else {
print("couln't pull that value")
}
//getting the timestamp
DataService.ds.REF_INTERESTS.child(interestKey).child("users").observeEventType(.Value, withBlock: { (snapshot: FIRDataSnapshot) in
// I can get the users children.count by doing yet another query, but my
// interestsArray gets all messed up and I get duplicates / weird
// loading in my tableview. So I'm looking to not do this whole
// separate query and just grab it from up above where I get the
// timestamp?
let snapshotChildren = String(Int(snapshot.childrenCount))
eachInterest.users = snapshotChildren
self.interestsArray.append(eachInterest)
//self.interestsArray.sortInPlace({ $0.latestUser < $1.latestUser })
dispatch_async(dispatch_get_main_queue(), {
self.tableView.reloadData()
})
})
})
}
}
}
}

Resources