How to get a specific value in firebase-realtime-database in swift 4.0
This is a standard Firebase Query.
To retrieve nodes that contain a child that has a certain value, we query the nodes for the node key in question and specify the value being looked for. They will be returned in a snapshot, and they can be more than one so we need to iterate over each of the returned snapshots.
let questionPostsRef = self.ref.child("questionPosts")
let query = questionPostsRef.queryOrdered(byChild: "trackId").queryEqual(toValue: "12345678")
query.observeSingleEvent(of: .value, with: { snapshot in
for child in snapshot.children {
let childSnap = child as! DataSnapshot
let dict = childSnap.value as! [String: Any]
let cat = dict["category"] as! String
let name = dict["name"] as! String
print(childSnap.key, cat, name)
}
})
and the output would be (assume two were found)
-Lu9ma9jsd... some category some name
-K999a90k9... some category some name
This is covered in the Firebase guide: Work With Lists Of Data in the Sorting and Filtering section
Now, the question states
And I want find the trackId that has the same value as my variable and
then get that trackId
Of course if you know the trackId already you wouldn't need to fetch it since you already have it. My guess is that you want to return the nodes that match that track ID so you can get to the other data, so that's what the above code does. If you are asking something different, let me know.
EDIT: a followup for the OP. To configure Firebase, this is the typical design pattern within a view controller. From there, you can reference your Firebase throughout this class with self.ref (as in my answer above)
import UIKit
import Firebase
import FirebaseAuth
import FirebaseDatabase
import FirebaseStorage
class ViewController: UIViewController {
var ref: DatabaseReference!
override func viewDidLoad() {
super.viewDidLoad()
self.ref = Database.database().reference()
Swift: Search for a specific value in Firebase Database & find all associated data
1. Realtime Database
Since you haven't included the structure of your database, I assume you have a database structure for drinks like below:
Screenshot of my Realtime database for this answer
{
"Drinks" : {
"-LYiUHm4vtrB3LqCBxEc" : {
"location" : "toronto",
"name" : "pepsi max",
"price" : 13.5,
"rating" : 3.6
},
"-LYiUHm5Lgt3-LENTdBZ" : {
"location" : "new york",
"name" : "diet coke",
"price" : 15.45,
"rating" : 5
},
"-LYiUHm5Lgt3-LENTdB_" : {
"location" : "chicago",
"name" : "mountain dew",
"price" : 2,
"rating" : 2
},
"-LYiUHm5Lgt3-LENTdBa" : {
"location" : "vancouver",
"name" : "sprite",
"price" : 6.98,
"rating" : 4.5
}
}
}
2. Swift 4.0
Now, to search any drink by name use below code:
func search(drinkName: String) {
let databaseRef = Database.database().reference().child("Drinks")
let query = databaseRef.queryOrdered(byChild: "name").queryStarting(atValue: drinkName).queryEnding(atValue: "\(drinkName)\\uf8ff")
query.observeSingleEvent(of: .value) { (snapshot) in
guard snapshot.exists() != false else { return }
//print(snapshot.value)
DispatchQueue.main.async {
// Update TextFields here
}
}
}
The \uf8ff character used in the query above is a very high code point in the Unicode range. Because it is after most regular characters in Unicode, the query matches all values that start with a b.
Source: https://firebase.google.com/docs/database/rest/retrieve-data
Note: queryOrderedByChild() is case-sensitive. It is nice practice to save all fields lowercased in database as this makes it easier to query data. You can always format strings in front end.
3. Add ".indexOn" to Realtime Database's Rules
In order to above query to work and achieve better performance, you need to set the index on the field that you are going to search by.
You can do this by going to Rules tab and adding index like below:
{
"rules": {
".read": true,
".write": true,
"Drinks": {
".indexOn": "name"
}
}
}
Source: More information on indexing data
Updated Answer for your updated question:
func searchT() {
// You must cast pub variable as String.
guard let pub: String = pubName.text else { return }
print(pub)
let databaseRef = Database.database().reference().child("Drinks")
let query = databaseRef.queryOrdered(byChild: "pub").queryStarting(atValue: pub).queryEnding(atValue: "\(String(describing: pub))\\uf8ff")
query.observeSingleEvent(of: .value) { (snapshot) in
guard snapshot.exists() != false else {
print("failing here")
return }
print(snapshot.value as Any)
DispatchQueue.main.async {
guard let dict = snapshot.value as? [String:Any] else {
print(snapshot)
return
}
let pubName = dict["pub"] as? String
let pubLocation = dict["location"] as? String
let price = dict["price"] as? String
let rating = dict["rating"] as? String
let comment = dict["comment"] as? String
}
}
}
Swift Get Specific Value From Firebase Database
At last I found a solution. If I declare a var and try to use later it returns nil, but if I try use snapshot.value as? String
it's ok. Here is a example I did.
ref: FIRDatabaseReference?
handle: FIRDatabaseHandle?
let user = FIRAuth.auth()?.currentUser
ref = FIRDatabase.database().reference()
handle = ref?.child("Kullanıcı").child((user?.uid)!).child("Yetki").observe(.value, with: { (snapshot) in
if let value = snapshot.value as? String{
if snapshot.value as? String == "admin"{
self.items.append("Soru Gönder")
self.self.tblView.reloadData()
}
}
})
Delete specific value from firebase database using swift
To write to or delete a node, you must specify its entire path. So to delete node 0
from your JSON, you'd do:
let usernameRef = Database.database().reference().child("Candidate 1").child("alton").child("0");
usernameRef.removeValue();
Or a bit shorter:
let usernameRef = Database.database().reference().child("Candidate 1/alton/0");
usernameRef.removeValue();
If you only know the name of the user you want to remove, you'll need to first look up its index/full path before you can remove it. If you have the data in your application already, you can do it in that code. Otherwise you may have to use a database query (specifically .queryOrderedByValue
and .queryEqualToValue
) to determine where the value exists in the database.
Also see: Delete a specific child node in Firebase swift
Once you remove a value from your JSON structure, Firebase may no longer recognize it as an array. For this reason it is highly recommended to not use arrays for the structure that you have. In fact, I'd model your data as a set, which in JSON would look like:
"alton": {
"Jake Jugg": true,
"Blake Wodruff": true,
"Alissa Sanchez": true
}
This would automatically:
- Prevent duplicates, as each name can by definition only appear once.
- Make removing a candidate by their name as easy as
Database.database().reference().child("Candidate 1/alton/Jake Jugg").removeValue()
For more on this, also see my answer to Firebase query if child of child contains a value
How to get data of a specific value from firebase realtime data in swift?
queryEqualToValue is changed. By queryEqual
ref.child("POSTBY").queryEqual(toValue: regex.encodeEmails(email).observe(.value) { snapshot in
for child in snapshot.children {
}
}
Unable to fetch and print a single value from a Firebase Database with Swift 5 (iOS)
You're adding an observer to /Users/$uid/email
, so the snapshot
you get contains just the value of the email
property. You are treating as a dictionary however, which explains why your code doesn't work.
To fix this, get the simple value from the
databaseReference.child("users").child((currentUser?.uid)!).child("email").observeSingleEvent(of: .value, with: { (snapshot) in
let valueRisk = snapshot.value as? String
print(valueRisk)
}) {(error) in
print(error.localizedDescription)
}
Reading child value from firebase database in swift
You need ( observe
/ observeSingleEvent
is up to you according to the logic of your app )
REF_FEEDMESSAGES.child("\(key)/likes").observeSingleEvent(of: .value, with: { (snapshot) in
// Get user value
}) { (error) in
print(error.localizedDescription)
}
Using this .value(forKey: "likes") as! String
for sure will crash the app , as it's not a local dictionary to query it's data synchronously
Related Topics
API to Capture Live Photos in iOS9
Change Title of a Navigation Bar Button Item
How to Convert Data Dictionary into an Array Swift
Swift Continuous Rotation Animation Not So Continuous
Save Depth Images from Truedepth Camera
Hidden Property Cannot Be Changed Within an Animation Block
How to Rotate a Scnsphere Using a Pan Gesture Recognizer
How to Create a Rounded Rectangle Label in Xcode 7 and Swift 2
How to Run a Task in Swift on a Particular Date-Time in Background Either Application Is on or Off
Uilocalnotification: Playing a Custom Audio File Saved in Documents Directory
Code Coverage Result Is Not Accurate to Real Coverage in Xcode 7
How to Change the Font Size of a Uilabel in Swift
Changing the Shape of a Uiview Border
Include Pods in Main Target and Not in Watchkit Extension
Self Sizing Uitextview Till Specific Height
Using Static Libraries with Cocoapods 1.5 No Such Module at Import