How to retrieve an specific child in Firebase? - ios

The childByAutoId would be useful if you want to save in a node multiple children of the same type, that way each children will have its own unique identifier.
pet:{
KJHBJJHB:{
name:fluffy,
owner:John Smith,
},
KhBHJBJjJ:{
name:fluffy,
owner:Jane Foster,
}
}
Therefore, once I have that uID, and I want to retrieve an specific user using the his/her uID. How do I tell Firebase that I want that specific user? Because I create it and store it in Firebase, but then to read it, don't I need to know the value of the uID? Where do I get it from?
What function do I use to retrieve for example the second user using the uID?
Thanks in advance..

in the title u ask how to get rid so:: get the new ref's key property to get the aid created
FIRDatabaseReference *ref = parent.childByAutoID
NSString *uid = ref.key
BUT thats not what you want id say, so:
to filter out all children where owner = XY which you want I think:
FIRDatabaseReference *ref = your pets node
FIRDatabaseQuery *allPets = [ref queryOrderedByChild:#"owner"];
FIRDatabaseQuery *specificPet = [allPets queryEqualToValue:#"XY"];
[specificPet observeEventType:FEventTypeChildAdded withBlock:^(FIRDataSnapshot *snapshot) {
NSDictionary *dict = snapshot.value;
NSString *key = snapshot.key;
NSLog(#"key = %# for child %#", key, dict);
}];
see: Query users by name or email address using Firebase (Swift)

Related

How to get chronologically latest post from Firebase?

I am working on app in which Facebook like news feed is used,and i am using Firebase as a database. Everything is working fine, I just need to fetch posts, time wise.
FIRDatabaseQuery * query = [[[_firebaseReference child:#"Demo"]child:#"posts"]queryLimitedToFirst:100];
[query observeSingleEventOfType:FIRDataEventTypeValue withBlock:^(FIRDataSnapshot * _Nonnull snapshot) {
if (snapshot.exists) {
postsDictionary = snapshot.value;
[self createSocialAppDataSource];
}
}];
The data in postsDictionary is same as in Database,But i want that data (post) to get sorted respect to time,So how to use query?
structure of my post in database as follow
Thanks
To filter the nodes on a child property, call queryOrderedByChild.
Then when you execute the query against the Firebase Database, there will potentially be multiple results. So the snapshot contains a list of those results. Even if there is only a single result, the snapshot will contain a list of one result.
So you'll need to loop over the children:
FIRDatabaseQuery * query = [[[[_firebaseReference child:#"Demo"] child:#"posts"] queryOrderedByChild: "dateTime"] queryLimitedToFirst:100];
[query observeSingleEventOfType:FIRDataEventTypeValue withBlock:^(FIRDataSnapshot * _Nonnull snapshot) {
for ( FDataSnapshot *child in snapshot.children) {
NSLog(#"child.key = %#",child.key);
}
}];
Loosely based on my answer here: IOS Firebase: Loop all key in snapshot.value get messy position
Usually people append the array they are feeding into the collectionView or tableView (for example) but in your case you can [myMutableArray insertObject:myObject atIndex:0]; now when you enumerate through your snapshot each post will be added to the front of your array

how to get the unique key that was created adding a child in firebase?

I am using firebase database for my ios project.
I added some fields using childByAutoId.
[[[_ref child:#"Users"] childByAutoId] setValue:#{#"data": #"my new json data string By aqeel", #"email": #"abc.xyz#email.com"}];
Now for some reason I have to search a specific child from database, say an email id. If email id exists I want to get that unique key of that child.
I am doing this
[[[[_ref child:#"Users"] queryOrderedByChild: #"email" ] queryEqualToValue:#"abc.xyz#email.com" ] observeEventType:FIRDataEventTypeValue withBlock:^(FIRDataSnapshot *snapshot) {
NSLog(#"%# Key %# Value", snapshot.key,snapshot.value);
}];
Here in key I get "Users" and in value I get all the entries inUsers field. But I want to get the key for the child abc.xyz#email.com.
Can someone provide me a sample code?
When you execute a query against the Firebase Database, there will potentially be multiple results. So the snapshot contains a list of those results. Even if there is only a single result, the snapshot will contain a list of one result.
This means that you will have to loop over the snapshot.children.
Alternatively you can listen for a single .ChildAdded event and get the child that way:
[[[[_ref child:#"Users"]
queryOrderedByChild: #"email" ]
queryEqualToValue:#"abc.xyz#email.com" ]
observeSingleEventOfType:FIRDataEventTypeChildAdded withBlock:^(FIRDataSnapshot *snapshot) {
NSLog(#"%# Key %# Value", snapshot.key,snapshot.value);
}];

Trouble with a Firebase Query

I am new to firebase because parse is shutting down and I have spent days trying to figure out how to find the parent of the child I am trying to query. For example let's say my parent is email and my child is person1. Now in my dictionary person1 is paired with person 1(there is a complicated reason why I am doing this but it is not a problem)
So my code looks like this.
Firebase *fb=[[Firebase alloc]initWithUrl:#"https:firebaseURL"];
[[[fb queryOrderedByChild:#"person1 string"] queryEqualToValue:#"person1 string"]
observeEventType:FEventTypeChildAdded withBlock:^(FDataSnapshot *snapshot) {
NSLog(#"888888%#", snapshot.key);
}];
NOTHING SHOWS
I really would appreciate the help. So basically I need to know how to query based on the child value and find the parent to that child. Thanks everyone.
A couple of things;
Your query is malformed. Ordered by defines what 'field' or node name you want to search.. it's the KEY part of the KEY:VALUE pair.
[fb queryOrderedByChild:#"person1 string"] should be
[fb queryOrderedByChild:#"node name to search"]
Let me break it down
Given
users
uid_0
name: "Jay"
state: "Florida"
uid_1
name: "Leroy"
state: "Colorado"
and code
// a reference to the parent node we want to query
Firebase *usersRef = [self.myRootRef childByAppendingPath:#"users"];
//define which child node name we want to search
FQuery *statesRef = [usersRef queryOrderedByChild:#"state"];
//define the value we want to search for
FQuery *specificStateRef = [statesRef queryEqualToValue:#"Florida"];
[specificStateRef observeEventType:FEventTypeChildAdded withBlock:^(FDataSnapshot *snapshot) {
NSLog(#"snapshot: %#", snapshot);
}];
snapshot will contain
uid_0
name: "Jay"
state: "Florida"
The parent node name is uid_0 and can be retrieved with
NSLog(#" key: %#", snapshot.key);
and the name and state are key value pairs stored in the value
NSLog(#" value: %#", snapshot.value);

Check if currentUser is the user that created the Post (iOS & Parse)

I want to check if the currentUser is the same as the user that created the post in order to display a button that would let the user delete that post.
I figured the best way would be to match the currentUser.objectId with the Post's "user Pointer<_User>".
I'm logging the currentUser's objectId with this code:
PFUser *currentUser = [PFUser currentUser];
NSString *currentUserID = currentUser.objectId;
NSLog(#"%#", currentUserID);
How can I log the Post's user Pointer<_User>?
Thanks.
First thing to do is to query the desired post object and then you can get the user pointer like retrieving the common value:
PFObject *post = ...; // I assume you know how to get your desired object
PFUser *postedUser = post[#"user"]; // user is the column name

iOS sort one array based on order of strings in another array

This is another very specific problem I am trying to solve.
I am pulling a list a twitter user accounts logged into the users settings application. This returns an array with the usernames in the correct order.
I then pass this array to this twitter API:
https://api.twitter.com/1.1/users/lookup.json
The returned array contain all the additional data I need for each user account logged in. The first array contains NSStrings (usernames), the returned array has been parsed to contain dictionaries that have a key and value for the username, name, and profile pic.
Problem now is that the order is completely different than the first array I passed.. This is expected behavior from Twitter, but it needs to be in the exact same order (I will be referencing the original index of the AccountStore which will match the first array, but not the new array of dictionaries).
How can I tell the new array to match the contained dictionaries to be the same order as the first array based on the username key?
I know this sounds confusing, so let me at least post the data to help.
Here is the first array output:
(
kbegeman,
indeedyes,
soiownabusiness,
iphonedev4me
)
Here is what the second array outputs:
(
{
image = "https://si0.twimg.com/profile_images/3518542448/3d2862eee546894a6b0600713a8de862_normal.jpeg";
name = "Kyle Begeman";
"screen_name" = kbegeman;
},
{
image = "https://si0.twimg.com/profile_images/481537542/image_normal.jpg";
name = "Jane Doe";
"screen_name" = iPhoneDev4Me;
},
{
image = "https://twimg0-a.akamaihd.net/profile_images/378800000139973355/787498ff5a80a5f45e234b79005f56b5_normal.jpeg";
name = "John Doe";
"screen_name" = indeedyes;
},
{
image = "https://si0.twimg.com/sticky/default_profile_images/default_profile_5_normal.png";
name = "Brad Pitt";
"screen_name" = soiownabusiness;
}
)
Due to the way Twitter returns the data, it is never the EXACT same order, so I have to check this every time I call these methods.
Any help would be great, would save my night. Thanks in advance!
You want the array of dictionaries be sorted by comparing screen_name value with your first array. Right? Also, the screen name may have different case than your username. Right?
I would use mapping dictionary:
Create dictionary from screen name to user dictionary:
NSArray *screenNames = [arrayOfUserDicts valueForKeyPath:#"screen_name.lowercaseString"];
NSDictionary *userDictsByScreenName = [NSDictionary dictionaryWithObjects:arrayOfUserDicts forKeys:screenNames];
Build final array by finding user dictionary for usernames in your array:
NSMutableArray *sortedUserDicts = [NSMutableArray arrayWithCapacity:arrayOfUsernames.count];
for (NSString *username in arrayOfUsernames) {
NSDictionary *userDict = [userDictsByScreenName objectForKey:username.lowercaseString];
[sortedUserDicts addObject:userDict];
}
First generate a mapping that maps the "screen_name" to the corresponding dictionary
in the second array:
NSDictionary *map = [NSDictionary dictionaryWithObjects:secondArray
forKeys:[secondArray valueForKey:#"screen_name"]];
Then you can create the sorted array with a single loop:
NSMutableArray *sorted = [NSMutableArray array];
for (NSString *name in firstArray) {
[sorted addObject:map[name]];
}
That sort order isn't something that could be easily replicated (i.e. it's not alpha, etc). Instead, you should just use that original NSArray as a guide to match data from the NSDictionary from Twitter. For example:
[twitterDictionary enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) {
NSInteger index = [yourLocalArray indexOfObject:obj];
if (index != NSNotFound) {
// You have a match, do something.
}
}];
lets name your arrays as firstArray and secondArray.
NSArray *sortedArray = [secondArray sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2) {
return [#([firstArray indexOfObject:[obj1 objectForKey:#"name"]]) compare:#([firstArray indexOfObject:[obj2 objectForKey:#"name"]])];
}];

Resources