Firebase database query by key value - ios

I have JSON like this.
livefeeds= {
"-KTn8pbqFHBUvgJ1Gwyl" = {
category = Alerts;
text = "Samsung Galaxy Note 7 owners told to turn off device";
timestamp = 1476179485648;
"user_id" = V7EFBV6uATf8urLXX9eK4EHhxmG2;
};
"-KTn8pbrhHyNzeLh2vOq" = {
category = News;
text = "Chicago Teachers Union, school board reach tentative contract agreement";
timestamp = 1476179485648;
"user_id" = V7EFBV6uATf8urLXX9eK4EHhxmG2;
};
}
I need to make query based on the key category.
Ex: If I only want Alerts, it should only retrieve category value equal to "Alerts" data only.
Here is query to retrieve livefeeds.
[[self.ref queryOrderedByChild:#"livefeeds"] observeEventType:FIRDataEventTypeValue withBlock:^(FIRDataSnapshot * _Nonnull snapshot) {
NSLog(#"---> %#",snapshot.value);
}];

First go till child "livefeeds" and then "queryOrderedByChild" category and use equal to child like this way
[[[[self.ref child:#"livefeeds"] queryOrderedByChild:#"category"]
queryEqualToValue:groupId]
observeEventType:FIRDataEventTypeValue withBlock:^(FIRDataSnapshot * _Nonnull snapshot) {
if (snapshot.value != [NSNull null]){
for (NSDictionary *snap in [snapshot.value allValues]) {
NSLog(#"---> %#",snap);
}
}
}];

Related

How to loop through Firebase childByAutoId in objective c

I need to loop through childByAutoId to add posts in array. So how can I access to price, title, text strings to load that data in my table?
Here is my base structure:
I read data from base in posts
[[_ref child:#"posts"]
observeEventType:FIRDataEventTypeValue
withBlock:^(FIRDataSnapshot *snapshot) {
[self.postData removeAllObjects];
// Loop over children
NSEnumerator *children = [snapshot children];
FIRDataSnapshot *child;
while (child = [children nextObject]) {
NSLog(#"child: %#", child);
[self.postData addObject:child];
}
NSLog(#"postData: %#", self.postData);
[self.postCollectionView reloadData];
}];
Here is my log:
2018-09-24 16:59:03.788023+0300 App[4904:1202383] child: Snap (-LNAfBgHiac83feC6Wm1) {
price = 3747;
text = Jfjfjf;
title = Jfjfjf;
}
2018-09-24 16:59:03.788125+0300 App[4904:1202383] child: Snap (-LNAfY-W7OZMA4Jm7TQN) {
price = 3764647;
text = Kgkgkg;
title = Blnckckc;
}
2018-09-24 16:59:03.788176+0300 App[4904:1202383] child: Snap (-LNArUfHbIV3y_hgACLr) {
title = Kgjggkkgnnc;
}
2018-09-24 16:59:03.788312+0300 App[4904:1202383] postData: (
"Snap (-LNAfBgHiac83feC6Wm1) {\n price = 3747;\n text = Jfjfjf;\n title = Jfjfjf;\n}",
"Snap (-LNAfY-W7OZMA4Jm7TQN) {\n price = 3764647;\n text = Kgkgkg;\n title = Blnckckc;\n}",
"Snap (-LNArUfHbIV3y_hgACLr) {\n title = Kgjggkkgnnc;\n}"
)
So it was that simple like
[self.postData addObject:child];
change to
[self.postData addObject:child.value];

Firebase sort query gives (unsorted) dictionary results

So I'm sure I'm missing something here, but when I wish to do a query for, say, the top 10 scores in a certain game, Firebase returns the top 10 scores, however since they are then gives back as a dictionary (key generated with childByAutoId), they are 'unsorted' when received on the client side (so to display a top 10 you have to sort them again)...
FIRDatabaseReference *ref = [[FIRDatabase database] reference];
FIRDatabaseQuery *jungleHighscoresQuery = [[[ref child:#"jungleScores"] queryOrderedByChild:#"score"] queryLimitedToLast:4];
[jungleHighscoresQuery observeSingleEventOfType:FIRDataEventTypeValue withBlock:^(FIRDataSnapshot * _Nonnull snapshot){
NSDictionary *postDict = snapshot.value;
NSLog(#"%#", postDict);
}];
The above code gives the following output (these are the top 4 scores among the ~20 in the database):
{
"-KIUhe_9TLQoy_zNbJT0" = {
score = 290;
userid = oMqoPGJYsGWHffYx8N6vDk3Osh72;
};
"-KIUj8VUyNMgyZ135dI_" = {
score = 560;
userid = oMqoPGJYsGWHffYx8N6vDk3Osh72;
};
"-KIUjK15Gy9PRB_JBWOA" = {
score = 240;
userid = oMqoPGJYsGWHffYx8N6vDk3Osh72;
};
"-KIUlZ1a03r7bjPYNueG" = {
score = 740;
userid = oMqoPGJYsGWHffYx8N6vDk3Osh72;
};
}
I know it's an easy task to just sort it all again, but it seems weird to have to do.
There was an easy solution after all, just had to grab the enumerator instead of the dictionary:
NSEnumerator *enumerator = snapshot.children;
and then just iterate through them with [enumerator nextObject]

Getting values from key in NSDictionary

I'm using the Edmunds API to return a JSON string of vehicle makes for a certain year.
The resulting NSDictionary looks like this:
makes = (
{
id = 200002038;
models = (
{ // not relevant
}
);
name = Acura;
niceName = acura;
},
{
id = 200001769;
models = (
{ // not relevant
}
);
name = "Aston Martin";
niceName = "aston-martin";
},
There are a lot more values in this dictionary...how can I loop through through the dictionary to retrieve each of the 'name' values?
I like valueForKeyPath because you can do so much with it and it's a one line solution. Tested this and it works in my dev setup. If you know your data is in a predictable format, then you can do amazing things with valueForKeyPath.
NSArray *makeNames = [makes valueForKeyPath:#"name"];
Great info on valueForKeyPath http://nshipster.com/kvc-collection-operators/
NSMutableArray *makeNames = [NSMutableArray new];
for (NSDictionary *make in makes) {
NSLog(#"Make name: %#", make[#"name"]);
[makeNames addObject:make];
}
NSLog(#"Makes array: %#", makeNames);

Comparing Dictionaries with Objects Value of Array in IOS

I am having N number of Dictionaries & having array that contains objects.
I need to iterate and check whether value for key EmployeeID of dictionary exists at Object. say obj.empId or not in array.
Dictionary looks like below
{
"Message":[
{
"EmpID": 3749,
"Dept": 10,
"EmployeeName": "John",
},
{
},
{
}]
} //so many dictionaries..not one
Example: I already have an array with 10 records say obj.empID holds from 1-10. From service I am getting 10 records say 10 dictionaries. In that key EmpID holds values 5-15.
So, How can I iterate the loop so that to identify that new records are retrieved with different EmpID's then existing Records.
Here is the Code I have done so far..
NSArray *responseArray=responseDict[#"Message"];
for (NSDictionary *dict in responseDict[#"Message"]) {
for (id key in responseDict) {
if ([key isEqualToString:#"EmpID"]) {
for (Employees *empObj in emparray)
{
BOOL isExists=YES;;
if (![empObj.empid isEqualToString:[responseDict objectForKey:key]]) {
isExists=NO;
break;
//here I need to do the logic..
}
}
}
}
}
But it will not get accurate results or logic is nor correct..
Please suggest any better solutions for above task or where I am going wrong..
Any Ideas or suggestions are appreciated..
Thanks..,
Without using so many loops, you may follow below code to check record is exist ot not.
NSArray *responseArray=responseDict[#"Message"];
for (Employees *empObj in emparray)
{
BOOL isExists=NO;
if ([[responseArray valueForKey:#"EmpID"]containsObject:empObj.empid]) {
isExists=YES;
NSLog(#"%# EmpID Exist",empObj.empid);
//here I need to do the logic..
}else{
NSLog(#"%# EmpID Not Exist",empObj.empid);
}
}
Dont use iterations, Code smartly, Use following code...
NSArray *responseArray=responseDict[#"Message"];
NSArray * empIdResponseArray = [responseArray valueForKeyPath:#"#unionOfObjects.EmpID"];
NSArray * empIdLocalArray = [emparray valueForKeyPath:#"#unionOfObjects.empid"];
NSMutableSet *empIdResponseSet = [NSMutableSet setWithArray: empIdResponseArray];
NSSet *empIdLocalSet = [NSSet setWithArray: empIdLocalArray];
[empIdResponseSet intersectSet: empIdLocalSet];
NSArray *commonElementArray = [empIdResponseSet allObjects];
NSMutableArray *newElementArray = [NSMutableArray arrayWithArray:empIdResponseArray];
[newElementArray removeObjectsInArray:commonElementArray];
for (int index = 0; index < newElementArray.count; index++)
{
NSMutableDictionary * dictEmp = [NSMutableDictionary dictionaryWithDictionary:[newElementArray objectAtIndex:index]];
NSLog(#"EMPLOYEE = %#",dictEmp);
// Add your Logic for new records only....
// Enjoy :)
}

Retrieve 1 specific key from several NSArrays and add them together

In my app, I am needing to loop through each NSArray, get the NSInteger associated with the key 'people' in the NSArray, and then add them all together. What would be a good starting point for first retrieving each specific NSInteger from each NSArray?
The array in question returns like this in console.
(
"<Prayers:DDomBXIONY:(null)> {\n Anonymous = 1;\n DeviceID = 123;\n FirstName = Name;\n LastName = Name;\n Location = HI;\n PrayerWarriors = 8;\n Request = Hi;\n Title = Hi;\n UserId = RtXN6QZsgaIiPw4SjFWGtkxXx;\n dateMade = \"Jan_09_2015\";\n}"
)
Basically just need to retrieve NSInteger from each PrayerWarriors key, and add them all together.
(
"<Prayers:DDomBXIONY:(null)> {\n Anonymous = 1;\n DeviceID = 123;\n FirstName = Name;\n LastName = Name;\n Location = HI;\n PrayerWarriors = 8;\n Request = Hi;\n Title = Hi;\n UserId = RtXN6QZsgaIiPw4SjFWGtkxXx;\n dateMade = \"Jan_09_2015\";\n}",
"<Prayers:yG7GC4bCIH:(null)> {\n Anonymous = 1;\n DeviceID = 123;\n FirstName = Name;\n LastName = Name;\n Location = bye;\n PrayerWarriors = 0;\n Request = bye;\n Title = bye;\n UserId = RtXN6QZsgaIiPw4SjFWGtkxXx;\n dateMade = \"Jan_09_2015\";\n}"
)
So without understanding exactly how your PFObject works, I'm going to assume it's like a dictionary.
Add each of your objects to a single array:
NSMutableArray *arrayHoldingPrayersObjects = [NSMutableArray alloc] init];
arrayHoldingPrayersObjects[0] = prayerObject1;
arrayHoldingPrayersObjects[1] = prayerObject2;
arrayHoldingPrayersObjects[2] = prayerObject3;
etc...
Then create a integer variable outside of a for loop and iterate through your objects, adding the value for PrayerWarrior at each iteration.
int totalPrayerWarriors = 0;
for (int i = 0; i < arrayHoldingPrayersObjects.count; i++)
{
NSMutableDictionary *prayerObject = arrayHoldingPrayersObjects[i];
totalPrayerWarriors += [prayerObject objectForKey:#"PrayerWarriors"] intValue];
}
You should end up with a correct total from all arrays. Do some tests to make sure it's accurate for you. Hope this helps.
*EDIT
The error you're getting indicates that it actually is a NSMutableArray, which you can't access using methods like objectForKey, so... there must be a method provided by PFObject that allows you to do that. OR, if PrayerWarriors is reliably the [5]th value (including 0) in the array, then you might be able to access it by index.
replace the lines:
NSMutableDictionary *prayerObject = arrayHoldingPrayersObjects[i];
totalPrayerWarriors += [prayerObject objectForKey:#"PrayerWarriors"] intValue];
with
NSMutableArray *prayerObject = arrayHoldingPrayersObjects[i];
totalPrayerWarriors += prayerObject[5];
Not sure where the mutable array is coming from. Parse.com will always produce immutable arrays as far as I know. So lets say you've retrieved Prayers with:
PFQuery *query = [PFQuery queryWithClassName:#"Prayers"];
[query findObjectsInBackgroundWithBlock:^(NSArray *prayers, NSError *error) {
// see how it's an NSArray, not mutable
}];
Now you want the total of the retrieved PrayerWarrior attributes, so...
[query findObjectsInBackgroundWithBlock:^(NSArray *prayers, NSError *error) {
NSInteger total = 0;
for (PFObject *p in prayers) {
NSNumber *warriorCount = p[#"PrayerWarriors"];
total += [warriorCount intValue]; // notice we cannot add nsnumbers directly (we need intValue)
}
NSLog(#"total warriors = %d", total);
}];

Resources