Querying Child Nodes Based on a Particular Value (Swift 3, Firebase) - ios

I am trying to pass a phone number (Ex. 1111111111) and see if it matches any of the entries in my Firebase Database. I am having problems sorting through the database and looking up the phone number. Below is the Firebase Database's JSON code.
{
"Users" : {
"3SMHwMuA8HQm9yLoivxYoCtUccr1" : {
"Email" : "firstname1.lastname1#gmail.com",
"First Name" : "First Name 1",
"Last Name" : "Last Name 1",
"Phone Number" : "(111) 111-1111"
},
"NvQiGzASw2QDAMcBQLx1HNzR8ZM2" : {
"Email" : "firstname2.lastname2#gmail.com",
"First Name" : "First Name 2",
"Last Name" : "First Name 2",
"Phone Number" : "(222) 222-2222"
},
"RuVMfHUC8qQg8KGVJitEkzq9Tsy2" : {
"Email" : "firstname3.lastname3#gmail.com",
"First Name" : "First Name 3",
"Last Name" : "Last Name 3",
"Phone Number" : "(333) 333-3333"
}
}
}
This is the code that I wrote. It is not giving the correct result.
phoneNumber: Int = 1111111111
ref = Database.database().reference()
let phoneNoInDatabase = ref.child("Users").queryEqual(toValue: phoneNo_pb_int)
let phoneNoInDatabaseInt = Int(phoneNoInDatabase.components(separatedBy: CharacterSet.decimalDigits.inverted).joined())
if phoneNoInDatabase_int == phoneNo_pb_int {
// Success!
print("User Found")
}
else {
// Error!
print("User not Found")
}

You're missing an instruction for what child to filter on:
let phoneNoInDatabase = ref.child("Users").queryOrdered(byChild: "Phone Number").queryEqual(toValue: phoneNo_pb_int)

Related

Firebase, get property by email

I have this database on Firebase:
{
"issues" : {
"-L04771_EjrLlv5u1-GU" : {
"issue" : "Test insert 1",
"last_edit" : "d8QICgTG5xR20RBzAXfzfu8gLgw2",
"owner" : "d8QICgTG5xR20RBzAXfzfu8gLgw2",
"owner_email" : "example1#gmail.com",
"status" : 1,
"url" : "http://www.example.com/example.html"
},
"-L047pIoqxkj4saaTYyQ" : {
"issue" : "Test insert 2",
"last_edit" : "d8QICgTG5xR20RBzAXfzfu8gLgw2",
"owner" : "d8QICgTG5xR20RBzAXfzfu8gLgw2",
"owner_email" : "example2#gmail.com",
"status" : 1,
"url" : "http://www.example.com/example.html"
}
}
}
I have to extract only those who have owner_email "example1#gmail.com".
Is possible?
You're probably looking for Firebase Queries and especially the equalTo-Query.
Your code would be something like this:
// Find all issues with owner_email = example1#gmail.com
var ref = firebase.database().ref("issues");
ref.orderByChild("owner_email").equalTo("example1#gmail.com").on("value", function(snapshot) {
// Loops through the matching issues
snapshot.forEach(function(child) {
console.log(child.key);
});
});

How can I save this object model data to Firebase

I have a model for a routine like the following:
struct Routine {
var routineName: String!
var routineExercisesAndSets: [String:Int]!
}
And a UITableView where I collect data before creating a new instance of that model, which once created looks like:
var routine = Routine()
//values are assigned to the routine here and then when printed looks like below
(routineName: All Over,
routineExercisesAndSets: ["Bent Over Row": 3, "Barbell Curl": 3, "Bench Press (Flat)": 4])
How could I save this into Firebase so that it fits my data structure
"routines": {
"users unique identifier": {
"routine unique identifier": {
"routine_name": "routine name",
"routine_create_date": "routine created date",
"exercises": {
"exercise name": {
"Sets": "number of sets",
"rest between sets": "timer duration"
}
}
}
}
}
The user unique identifier will be the current logged in users uid and routine unique identifier will be an autoId, but how can I work through the model to push data to Firebase the same as the model?
If your user is authenticated try this:-
FIRDatabase.database().reference().child("routines/\(FIRAuth.auth()!.currentUser!.uid)").childByAutoId().setValue([
"routine_Name" : "All Over",
"routine_create_date": "routine created date",
"exercises": [
"exercise name": [
"Sets": "number of sets",
"rest between sets": "timer duration"
]]
])

Firebase fanout data to update specific fields remove other siblings fields

Each user has a conversation node, each time a new conversation has a new message I need to update both conversation nodes for the two user involved in the conversation, I want just to update the "lastMessage" and "tinestamp" fields here is my try:
let fanoutObject = [userPath : dataToUpdate,
otherUserPath : dataToUpdate]
K.FirebaseRef.root.updateChildValues(fanoutObject)
where the paths for each user is:
"/users/{userID}/conversations/{conversationID}"
and the dataToUpdate:
let dataToUpdate:[String:AnyObject] = ["timestamp" : message.timestamp,
"lastMessage": message.textBody]
Result:
The node conversations for each user is updated BUT other fields in the conversation node are removed !
the conversation node fro each user is:
"conversations" : {
"{conversationID}" : {
"lastMessage" : "your name ?",
"seen" : true,
"timestamp" : 1467849600000,
"with" : {
"country" : "US",
"firstName" : "John",
"profileImage" : "https://..."
}
}
}
note that the node conversations is inside a node user which is an element inside the root node users
and after update it's :
"conversations" : {
"{conversationID}" : {
"lastMessage" : "your name ?",
"timestamp" : 1467849600000,
}
}
but I was expecting just to update the two values and keep others ?
According to docs my code should works:
updateChildValues Update some of the keys for a defined path without
replacing all of the data.
It's a bit hard to parse your code, but most likely it's the behavior of updateChildValues() that is confusing you.
When you call updateChildValues(), the Firebase server will loop over the object that you pass in. For each path in there, it will replace the entire value at that path with the value from that you passed in.
So if your current JSON is:
{
"Users": {
"uidForUser1": {
"name": "iOSGeek",
"id": 2305342
},
"uidForUser2": {
"name": "Frank van Puffelen",
"id": 209103
}
}
And the update is (in JSON format, the lingua franca of the Firebase Database):
{
"users/uidForUser2/name": "puf",
"users/uidForUser1/name": "My actual name"
}
Your resultant JSON will be:
{
"Users": {
"uidForUser1": {
"name": "My actual name",
"id": 2305342
},
"uidForUser2": {
"name": "puf",
"id": 209103
}
}
But if you send the following update:
{
"users/uidForUser1": {
"name": "My actual name"
},
"users/uidForUser2": {
"name": "puf"
}
}
The resulting JSON will be:
{
"Users": {
"uidForUser1": {
"name": "My actual name"
},
"uidForUser2": {
"name": "puf"
}
}
Update
To update two fields in the same object, but leave the other fields unmodified:
{
"path/to/object/field1": "new value",
"path/to/object/field2": "new value2"
}
Alternatively, you can update the lastMessage and timeStamp data by replacing the old values by providing full path :
let lastMessagePath = "/users/{userID}/conversations/{conversationID}/lastMessage"
let lastTimeStampPath = "/users/{userID}/conversations/{conversationID}/timestamp"
K.FirebaseRef.child(lastMessagePath).setValue(message.timestamp)
K.FirebaseRef.child(lastTimeStampPath).setValue(message.textBody)

Firebase query with queryOrderedByKey().queryLimitedToLast(10) does not return one of the last 10 items

I am trying to load the last 10 products that have been added to the all_products table in firebase.
I run the following query with version 3.2.0 of the firebase SDK:
let fbRef = FIRDatabase.database().reference().child("products_all").queryOrderedByKey().queryLimitedToLast(10).observeSingleEventOfType(.Value, withBlock: { snapshot in
for item in snapshot.children {
let keyString = (item as! FIRDataSnapshot).key
However, the items that get returned are not the last 10 items in this table. I have about 1017 products in this table and the first item that gets returned in this query is item 973, while it should be item 1008.
My firebase looks like this (I used childByAutoId to add the products):
{
"products_all" : {
"-KFOiZDrbR4eq4fXSdMZ" : {
"affiliate_url" : "https://some.link.com",
"description" : "product description",
"image_url" : "https://image.url.com/firstImage.jpg",
"images" : [ "https://image.url.com/firstImage.jpg", "https://image.url.com/secondImage.jpg" ],
"merchant" : "merchant.com",
"price_usd" : "100.00",
"title" : "product title"
},
...,
"-KFtOmT_Hq-48chbHh7I" : {
"affiliate_url" : "https://another.link.com",
"description" : "another product description",
"image_url" : "https://image.link.com/anotherImage.jpg",
"images" : [ "https://image.link.com/anotherImage.jpg" ],
"merchant" : "anothermerchant.com",
"original_currency" : "GBP",
"original_price" : "255",
"price_usd" : "364.65",
"product_category" : "Bracelet",
"external_product_id" : "Anothermerchant-123",
"title" : "another product title"
},
...,
"-KFtOmTlcb5-PTQ6kTv8" : {
"affiliate_url" : "https://last.product.com",
"description" : "last product description",
"image_url" : "https://last.product.com/image.jpg",
"images" : [ "https://last.product.com/image.jpg" ],
"merchant" : "anothermerchant.com",
"original_currency" : "GBP",
"original_price" : "179",
"price_usd" : "268.5",
"product_category" : "Bracelet",
"scraped_product_id" : "anothermerchant-493",
"title" : "last product title"
}
}
}
EDIT: Also, the last element in the batch of 10 is number 992 - so the 10 items are neither in the last 10, nor are their all 'neighbours'.
First keys that were included:
-KFtOmT_Hq-48chbHh7I
-KFtOmT_Hq-48chbHh7J
-KFtOmT_Hq-48chbHh7K
Subsequent keys that were skipped:
-KFtOmT0Qj3mrCTlxOfj
-KFtOmT1jouJgm8x_Mi7
-KFtOmT4GUpXtd9Y90sq
-KFtOmT4GUpXtd9Y90sr
-KFtOmT57vidxDl_jpj_
-KFtOmT57vidxDl_jpja
-KFtOmT9yuy-1G8WBrsE
Then some keys were included and others again excluded, the 'coverage' is patchy.

How to remove first and last { } in a NSString in iOS?

I want to remove first and last bracket from my NSString.
{
"Questions" : [
{
"title" : "This is my Question",
"question_id" : "123123123213",
"answers" : [
"correct answer 1",
"wrong answer 1",
"wrong answer 2",
"wrong answer 3"
],
"media_type" : "",
},
{
"title" : "This is my Question",
"question_id" : "2342342342342",
"answers" : [
"correct answer 1",
"wrong answer 1",
"wrong answer 2",
"wrong answer 3"
],
"media_type" : "",
}
]
}
I want to remove only first and last { } from the above NSString.
Make sure its not Dictionary. I have this in NSString.
UPDATE
The option is serializing:
NSData *data = [str dataUsingEncoding:NSUTF8StringEncoding];
NSDictionary *dictJson = [NSJSONSerialization JSONObjectWithData:data
options:kNilOptions
error:nil];
NSArray *arr = dictJson[#"Questions"];
for (NSDictionary *dict in arr)
{
NSLog(#"title ==%#",dict[#"title"]);
.....
}
UPDATE 2
But BE CAREFUL with your string. It's wrong. You have to check the commas after media_type:
{
"Questions" : [
{
"title" : "This is my Question",
"question_id" : "123123123213",
"answers" : [
"correct answer 1",
"wrong answer 1",
"wrong answer 2",
"wrong answer 3"
],
"media_type" : ""**,** //THIS
},
{
"title" : "This is my Question",
"question_id" : "2342342342342",
"answers" : [
"correct answer 1",
"wrong answer 1",
"wrong answer 2",
"wrong answer 3"
],
"media_type" : ""**,** //AND THIS
}
]
}
No commas have to go there.

Resources