Fetching Current User Profile using Objective C Google Plus Client Library - ios

I am using the Google CLient Libraries for Objective C available here..
I have successfully been able to Authorize the user and get refresh token. (Using the GTMOAuthenticaion api embedded within).
In the Selector called after successful authorization I make the Get User Profile request as follows.. (I need the id of currently loggedin/authenticated user)
-(void)viewController:(GTMOAuth2ViewControllerTouch *)viewController
finishedWithAuth:(GTMOAuth2Authentication *)auth
error:(NSError *)error {
if (error != nil) {
NSLog(#"Stop");
} else {
if ([auth canAuthorize]){
[Mediator plusService].authorizer = auth;
// Problematic Line
GTLQueryPlus *profileQuery = [GTLQueryPlus queryForPeopleGetWithUserId:#"me"]; // Notice the UserId Param
profileQuery.completionBlock = ^(GTLServiceTicket *ticket, id object, NSError *error) {
if (error == nil) {
self.mediator.gProfile = object;
} else {
NSLog(#"GPlus Service Error %#", error);
}
};
[[Mediator plusService] executeQuery:profileQuery completionHandler:
^(GTLServiceTicket *ticket, id result, NSError *error) {
if (error)
NSLog(#"Some Service Error %#", error);
}];
}
}
}
If I put "me" as parameter, I get invalid user ID error string in jSON response.
However, If I provide some userId like my own 113632923069489732066 it works perfectly fine and returns the appropriate jSON response..!!
The Example for Google Plus inside Examples folder also fails to get current user profile ending with following error.
Error Domain=com.google.GTLJSONRPCErrorDomain Code=400 "The operation couldn’t be completed. (Invalid user ID: {0})" UserInfo=0x7a670fa0 {NSLocalizedFailureReason=(Invalid user ID: {0}), GTLStructuredError=GTLErrorObject 0x7a67b130: {message:"Invalid user ID: {0}" code:400 data:[2]}, error=Invalid user ID: {0}}
P.S. My API Console application doesn't work with iOS option under installed app but needs be configured with "Other" option. When configured with iOS option, the oAuth fails with invalid_client error response.

My Mistake .. !! And a very silly one .. !!
I was signing in using a Gmail Account that was yet not associated with GPlus .. !! =/

Related

Google Drive on iOS and "invalid_grant"

I have an iOS app that uses Google Drive to sync some files. The app was working fine up until a couple of months ago (it uses iCloud by default for syncing so it wasn't until recently that I learned the Google Drive since was no longer working).
The error I'm getting is:
An error occurred: Error Domain=com.google.HTTPStatus Code=400 "(null)" UserInfo={json={
error = "invalid_grant";
}, data=<7b0a2020 22657272 6f722220 3a202269 6e76616c 69645f67 72616e74 220a7d>}
The OAuth part sets to be OK and I think I'm authorized to access the user's Google Drive. The error happens when I try to list the files at the top level to see if I need to create a special directory for my app.
- (void)createGoogleDocumentsDirIfNeeded:(id<GoogleServiceDelegate>)delegate
{
NSString *parentID = #"root";
GTLQueryDrive *query = [GTLQueryDrive queryForFilesList];
query.q = [NSString stringWithFormat:#"'%#' in parents and title = '%#' and trashed != true", parentID, APP_NAME];
[googleService executeQuery:query completionHandler:^(GTLServiceTicket *ticket,
GTLDriveFileList *files,
NSError *error)
{
if (error == nil)
{
if ( files.items.count == 0)
{
NSLog(#"Creating google documents dir: %#", APP_NAME);
[self createGoogleDocumentsDir:delegate];
}
else
{
GTLDriveFile *file = [files objectAtIndexedSubscript:0];
self.googleDocumentsID = file.identifier;
NSLog(#"Directory exists: %#; fileID = %#", APP_NAME, googleDocumentsID);
[delegate googleDocumentsDirCreated:YES];
}
}
else
{
NSLog(#"An error occurred: %#", error);
}
}];
}
The error is displayed in the last NSLog().
I'm pretty convinced that something has change on Google's side that is causing this. I've reverted to code to a point where I know it worked before and it is still failing.
Possibly I've made some change in our Google Developer's Console that is causing this, but I can't see what.
It is also the case that the Google API Dashboard still shows some successful accesses, so it seems this is not failing for everyone.
Any thoughts as to what could be going on? The "invalid_grant" error seems pretty generic and web searches show it happens in lots of situations. Any help would be appreciated.
As you say, there could be a variety of explanations.
Some to check are:-
has the user withdrawn his permission
are you using an expired refresh token
is the phone's clock accurate
Read https://developers.google.com/identity/protocols/OAuth2UserAgent
The URL used when authenticating a user is https://accounts.google.com/o/oauth2/v2/auth. This endpoint is accessible over SSL, and HTTP connections are refused.
Only for httpS connects for now

Parse iOS: PFUser saveInBackgroundWithBlock does not return error when the save does not succeed

I am using anonymous users in parse and if they are not saved, I issue a network call to save them. The code for saving the user is as follows
PFUser* current = [PFUser currentUser];
if (!current.objectId) {
// The user is newly created, don't run any queries for them until they are saved.
[current saveInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {
// We need a saved user to do stuff.
if (!succeeded) {
NSLog(#"Error saving user: %#", error);
} else {
NSLog(#"Saved anonymous user");
// ... load data
}
}];
return;
}
If I run this in the simulator with no internet connection, the save fails (clearly), but succeeded is true and error is nil, so my code goes into loading data even though the user was not saved. In fact the error gets logged in logs but isn't returned in the callback:
Error: Error
Domain=NSURLErrorDomain Code=-1009 "The Internet connection appears to
be offline." UserInfo=0x17aa1220
{NSErrorFailingURLStringKey=https://api.parse.com/2/user_signup_or_login,
NSErrorFailingURLKey=https://api.parse.com/2/user_signup_or_login,
NSLocalizedDescription=The Internet connection appears to be offline.,
NSUnderlyingError=0x1792c880 "The Internet connection appears to be
offline."} (Code: 100, Version: 1.2.20)
Is this a bug in the Parse API or am I not using something correctly?
It is not enough to just check the succeeded flag, you should also check the error.
If you are only going to check one of them, check the error.
The following is the pattern I would use:
if (succeeded && !error) {
// success!
} else {
// uh oh :(
}
You can handle the error in the else block by using kPFErrorConnectionFailed which checks for connection.
Example
else {
if(error.code == kPFErrorConnectionFailed)
{
// handle error
}
}
This was a bug which has now been fixed in the latest release of parse.

Unable to obtain origin of NSLog in a Parse block?

I am using the following code to log in a user to my application using parse.com
[PFUser logInWithUsernameInBackground:usernameString password:passwordString
block:^(PFUser *user, NSError *error) {
if (user) {
// Do stuff after successful login.
NSLog(#"The user has logged in");
} else {
// The login failed. Check error to see why.
}
}];
The code works great and is documented on the Parse.com API Documentation HERE
My problem however is that I want to be able to show an alert to users when their login credentials come back with with an error, currently I get the following error on my console when I try to sign in with invalid credentials: Error: invalid login credentials (Code: 101, Version: 1.2.19)
Thats great, but I have looked everywhere and cant seem to find where that code, is being created... I am looking for it so that I can add different error messages for to my users: i.e.
if ([errorString rangeOfString:#"username"].location == NSNotFound) {
//the issue is not username related
} else
{
NSLog= (#"The username has been taken");
}
Any idea how I can find the string that contains the error and examine it so that I may act accordingly to the error?
the parse error codes are all documented here:
https://parse.com/docs/ios/api/Classes/PFConstants.html
101 is kPFErrorObjectNotFound
and means 'Object doesn't exist, or has an incorrect password.'
during a login it is likely more the later ;)
so:
if(error.code == kPFErrorObjectNotFound) {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"parse login error" message:#"Invalid credentials" delegate:nil cancelButtonTitle:#"ok"];
[alert show];
}
dont use the error string of an NSError as you can't really tell if it is suitable for display.
still it is likely in localizedDescription or some other userInfo field
If you look at the documentation for NSError you will see that its userInfo property is a dictionary. From your NSLog you can see that the error key contains the string you are after, so you can access it with
NSString *errorMessage=[error.userInfo objectForKey:#"error"];
Although, rather than parsing strings it is safer to check the error.code value for 101, possibly displaying the error message for more detail. Checking the error code rather than the string will ensure that a change in the string by Parse won't break your code

stackmob ios datastore http 401 error

I'm using the iOS DataStore API to upload data to StackMob. I get this error when I try to use my smclient initialized with my public key.
HTTP Code=401 "The operation couldn’t be completed. (HTTP error 401.)" UserInfo=0xa14dac0 {error=Insufficient authorization}
Sample code
[[self.smclient dataStore] createObject:eventDictObj
inSchema:#"EventSchema"
onSuccess:^(NSDictionary *object, NSString *schema)
{
NSLog(#"Created online event : %#", object);
successBlock();
}
onFailure:^(NSError *error, NSDictionary* object, NSString *schema)
{
failedBlock(error);
}];
And smclient is initialized as follows
self.smclient = [[SMClient alloc] initWithAPIVersion:#"0" publicKey:#"xxxxxxxxxx"];
For this use case I don't need to use the logged in user credentials to create this entry in StackMob
Make sure that the permissions are set to Open on your stack mob database.

Error when trying to retrieve basic user information

I have successfully included the Facebook Login in my IOS app however i seem to be having some difficulty getting some of the users basic information such as name, email etc....
My current code looks like this:
// Ask for the required permissions
self.loginView.readPermissions = #[#"basic_info",
#"user_location",
#"user_birthday",
#"user_likes"];
// Fetch user data
[FBRequestConnection
startForMeWithCompletionHandler:^(FBRequestConnection *connection,
id<FBGraphUser> user,
NSError *error) {
if (!error) {
// Display the user info
tempLabel.text = user.name;
}
}];
However there is always an error (where the if statement checks for !error, its always equal to false).
Can someone help me in trying to get this please?
Thanks,
Jake
EDIT:
2013-08-04 15:52:03.457 Ludis[37821:c07] {
"com.facebook.sdk:HTTPStatusCode" = 400;
"com.facebook.sdk:ParsedJSONResponseKey" = {
body = {
error = {
code = 2500;
message = "An active access token must be used to query information about the current user.";
type = OAuthException;
};
};
code = 400;
};
}
2013-08-04 15:52:03.458 Ludis[37821:c07] The operation couldn’t be completed. (com.facebook.sdk error 5.)
You haven't obtained the user's permission to perform the action you're attempting to perform. First call
openActiveSessionWithReadPermissions:allowLoginUI:completionHandler:
on FBSession. Here's some more information about how to log in to Facebook from iOS

Resources