To answer my own question, I noticed that Firebase keys are always strings, so for example if I set a key to "123", the url for that node becomes:
https://xxxxx.firebaseio.com/%22123%22
So it simplified my objective-c code quite a bit to follow the key-as-string convention with my NSDictionaries. I also decided to store numeric values representing user ids as strings in Firebase because it simplifies using those values later for lookups like:
[[myFirebase childByAppendingPath:snapshot.value] observeSingleEventOfType:FEventTypeValue withBlock:]
The only tricky part is that if I make a call to Facebook like:
[[FBRequest requestForMe] startWithCompletionHandler:^(FBRequestConnection *connection, id result, NSError *error) {
NSLog(@"%@", [result[@"id"] class]);
}];
The result is:
__NSCFString
But if I make a call to Facebook with FQL like:
[[FBRequest requestWithGraphPath:@"fql" parameters:@{@"q": @"SELECT uid, name FROM user WHERE uid = me()"} HTTPMethod:nil] startWithCompletionHandler:^(FBRequestConnection *connection, id result, NSError *error) {
NSLog(@"%@", [result[@"data"][0][@"uid"] class]);
}];
The result is:
__NSCFNumber
Notice that Facebook returns some ids as strings and others as numbers! Also there is no “as” clause in FQL so we can’t return uid as id, which is annoying, but I digress.
So it’s important to convert these types to NSString before storing them like:
[myFirebase setValue:@{@"test" : result[@"data"][0][@"uid"]}];
Otherwise when you retrieve them and try to use them with childByAppendingPath:snapshot.value, it barfs. So just use:
[myFirebase setValue:@{@"test" : [result[@"data"][0][@"uid"] stringValue]}];
You can write a category on NSString to avoid annoying “unrecognized selector sent to instance” exceptions:
@implementation NSString(stringValue)
- (NSString *)stringValue
{
return self;
}
@end
I’m not super comfortable with this because it would be more efficient to use numbers directly, but, it allows for future expandability with alphanumeric ids, and also since most ids are on the order of 8 digits anyway, they take up about the same amount of room as binary or text in the Firebase stream regardless. For other things like timestamps, scores, etc, I’ve decided to store numbers directly since they generally aren’t used later for lookups.
Just thought this might help someone save some time. I’m still curious about alternatives.
Zack Morris