Hi, I’m experimenting with login with Facebook and I have a problem:
I use a field mapping with first_name, last_name, birthday, gender. The method loginWithFacebookSDK:fieldsMapping: doesn't seem to retrieve these fields from Facebook. Instead, I have to manually invoke a Graph request then update the user with [backendless.userService update:user];
However, the update: method of the UserService doesn't filter the user-registered field and fails when this field is present. I have to remove it myself prior to calling the update: method with [[user getProperties] removeObjectForKey:@"user-registered"]; Is this the right way?
Thanks!
Hi,
Are you guys following up on that?
Thanks
Hi Emmanuel,
We are investigating an issue and we’ll let you know asap.
Regards,
Slava
Hi, Emmanuel!
When you use loginWithFacebookSDK method for the first time the user is both registered and logged in. If facebookFieldsMapping are provided, they are used while registering user. When the method loginWithFacebookSDK is invoked again for the same user, the user is logged without registering (the fieldsMapping provided during registration are used). If you want to use the new fieldsMapping for this user you can either:
- Delete the user and register him again with the new fieldsMapping.
- Invoke a Graph request and then update the user with [backendless.userService update:user]; (what you do now).
Concerning the second part of your request, appropriate changes are made to iOS SDK, you can now invoke UserService update method without prior removing “user-registered” from user entity.
You can download the latest iOS SDK code here: https://github.com/Backendless/ios-SDK/tree/master/SDK
Hi Anatolii,
For the first part, to be clear, I am not trying to change the user mapping for an existing user.
Here is my code:
NSDictionary *fieldsMapping = @{
@"id" : @"facebookId",
@"name" : @"name",
@"birthday": @"birthday",
@"first_name": @"first_name",
@"last_name" : @"last_name",
@"gender": @"gender",
@"email": @"email"};
@try {
BackendlessUser *user = [backendless.userService loginWithFacebookSDK:accessToken fieldsMapping:fieldsMapping];
[backendless.persistenceService load:user relations:@[@"profilePic"]];
id userRegistered = [user getProperty:@"user-registered"];
if (userRegistered && userRegistered != [NSNull null]) {
NSString *fields = [[fieldsMapping allKeys] componentsJoinedByString:@","];
FBSDKGraphRequest *requestForName = [[FBSDKGraphRequest alloc]
initWithGraphPath:@"me"
parameters:@{@"fields" : fields}];
[requestForName startWithCompletionHandler:^(FBSDKGraphRequestConnection *connection,
NSDictionary *result,
NSError *queryError) {
FBSDKGraphRequest *requestForImageUrl = [[FBSDKGraphRequest alloc]
initWithGraphPath:@"me"
parameters:@{@"fields" : @"picture.type(large)"}];
[requestForImageUrl startWithCompletionHandler:^(FBSDKGraphRequestConnection *connection,
NSDictionary *picture,
NSError *queryError) {
NSURLSession *session = [NSURLSession sharedSession];
[[session dataTaskWithURL:[NSURL URLWithString:picture[@"picture"][@"data"][@"url"]]
completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
BLMFile *profilePic;
if (!error) {
profilePic = [BLMFile fileWithName:[NSString stringWithFormat:@"user/%@.jpg", [[NSUUID UUID] UUIDString]] mime:@"application/jpeg" data:data];
[user addProfilePic:profilePic];
}
[backendless.userService setPersistentUser];
for (NSString *field in [fieldsMapping allKeys]) {
[user setProperty:fieldsMapping[field] object:result[field]];
}
dispatch_async(dispatch_get_main_queue(), ^{
[user
save:^(id response) {
[self notifyLogin:user error:nil];
}
error:^(Fault *fault) {
NSLog(@"FAULT = %@ <%@>", fault.message, fault.detail);
NSError *error = [NSError errorWithDomain:BLMERROR_DOMAIN code:[fault.faultCode integerValue] userInfo:@{NSLocalizedDescriptionKey: fault.message}];
[self notifyLogin:nil error:error];
}];
});
}] resume];
}];
}];
}
else {
[self notifyLogin:user error:nil];
}
}
@catch (Fault *fault) {
NSLog(@"Login with Facebook failed: %@", fault);
NSError *error = [NSError errorWithDomain:BLMERROR_DOMAIN code:[fault.faultCode integerValue] userInfo:@{NSLocalizedDescriptionKey: fault.message}];
[self notifyLogin:nil error:error];
}
Sorry if it’s a bit long but it explains what I do better than many words :))
In a nutshell, the Facebook details are not retrieved by the loginWithFacebookSDK:fieldsMapping: method on registration (user creation). I need to perform a Facebook request myself then update the user. I expect from the method to do that for me, otherwise what is the point of using field mapping?
Thanks!
Hi Emmanuel,
The Backendless SDK 3.0.5 version has been deployed to Cocoapods, it fixes this issue.
Regards,
Slava