facebook didCompleteWithResult - ios

im using facebook login in my app and a want to proceed user to main interface after he logged oon facebook.
Here is how im handling results:
- (void)loginButton:(FBSDKLoginButton *)loginButton didCompleteWithResult:(FBSDKLoginManagerLoginResult *)result error:(NSError *)error {
if (error) {
NSLog(#"FB login failed");
}
else if (result.isCancelled) {
NSLog(#"FB login cancelled");
}
else {
[self performSegueWithIdentifier:#"fbLogin" sender:self];
NSLog(#"User logged in");
}
}
The problem is that in good case my NSLog(#"User logged in"); calls, but segue doesnt perform
Added:
Here is my viewDidLoad method to provide login button:
- (void)viewDidLoad {
[super viewDidLoad];
fbLoginButton.readPermissions = #[#"public_profile"];
fbLoginButton.publishPermissions = #[#"publish_actions"];
fbLoginButton.delegate = self;
}
And AppDelegate.m :
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[[FBSDKApplicationDelegate sharedInstance] application:application
didFinishLaunchingWithOptions:launchOptions];
[FBSDKLoginButton class];
[FBSDKShareButton class];
return YES;
}
I also want to say, that login works correctly, its just segue problem

Related

Google sign in for iOS using firebase is giving 400 error

I am trying to implement Google Sign in for iOS, I followed all the steps mentioned on https://firebase.google.com/docs/auth/ios/google-signin to setup Google sign in, but when I get the GIDSignInDelegate callback
- (void)signIn:(GIDSignIn *)signIn didSignInForUser:(GIDGoogleUser *)user withError:(NSError *)error
I get HTTP error code as 400 with user object as nil and description as
Error data:
{
error = "invalid_grant";
"error_description" = "verifier does not match.";
}
My code is pretty simple, just implemented a Google sign in button and my View controller implements GIDSignInDelegate.
Demo code:
In AppDelegate.m
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[FIRApp configure];
[GIDSignIn sharedInstance].clientID = [FIRApp defaultApp].options.clientID;
PBLoginSignupUserViewController *loginSignupVC = [[PBLoginSignupUserViewController alloc] init];
UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:loginSignupVC];
self.window.rootViewController = navController;
return YES;
}
- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options {
return [[GIDSignIn sharedInstance] handleURL:url sourceApplication:options[UIApplicationOpenURLOptionsSourceApplicationKey] annotation:options[UIApplicationOpenURLOptionsAnnotationKey]];
}
In MyViewController.m <GIDSignInUIDelegate, GIDSignInDelegate>
- (void)signIn:(GIDSignIn *)signIn didSignInForUser:(GIDGoogleUser *)user withError:(NSError *)error {
// GETTING ERROR HERE, AND nil AS USER OBJECT
if(!error){
GIDAuthentication *authentication = user.authentication;
FIRAuthCredential *credential = [FIRGoogleAuthProvider credentialWithIDToken:authentication.idToken
accessToken:authentication.accessToken];
} else {
// show toast for error
}
}

Facebook login for parse iOS app not working

I've added the facebook login button as described in the tutorial here. When I try testing this out however, the FB login button simply shows a loading indicator and the app freezes up. Is there any other integration I forgot to implement?
AppDelegate.m:
- (BOOL)application:(UIApplication *)application
openURL:(NSURL *)url
sourceApplication:(NSString *)sourceApplication
annotation:(id)annotation {
return [[FBSDKApplicationDelegate sharedInstance] application:application
openURL:url
sourceApplication:sourceApplication
annotation:annotation];
}
- (void)applicationDidBecomeActive:(UIApplication *)application {
[FBSDKAppEvents activateApp];
}
- (void)applicationDidBecomeActive:(UIApplication *)application {
// Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
// Start updating locations when the app returns to the foreground.
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"MainStoryboard" bundle:nil];
DefaultSettingsViewController *defaultSettingsViewController = [storyboard instantiateViewControllerWithIdentifier:#"DefaultSettingsViewController"];
//[defaultSettingsViewController.locationManager stopUpdatingLocation];
// Clear badge when app is opened
PFInstallation *currentInstallation = [PFInstallation currentInstallation];
if (currentInstallation.badge != 0) {
currentInstallation.badge = 0;
[currentInstallation saveEventually];
}
[FBSDKAppEvents activateApp];
[FBAppCall handleDidBecomeActiveWithSession:[PFFacebookUtils session]];
}
DefaultViewController.m:
- (void)_loginWithFacebook {
// Set permissions required from the facebook user account
NSArray *permissionsArray = #[ #"user_about_me", #"user_relationships", #"user_birthday", #"user_location"];
// Login PFUser using Facebook
[PFFacebookUtils logInInBackgroundWithReadPermissions:permissions block:^(PFUser *user, NSError *error) {
if (!user) {
NSLog(#"Uh oh. The user cancelled the Facebook login.");
} else if (user.isNew) {
NSLog(#"User signed up and logged in through Facebook!");
} else {
NSLog(#"User logged in through Facebook!");
}
}];
}
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
if (![PFUser currentUser]) { // No user logged in
// Create the log in view controller
PFLogInViewController *logInViewController = [[PFLogInViewController alloc] init];
[logInViewController setDelegate:self]; // Set ourselves as the delegate
[logInViewController setFacebookPermissions:[NSArray arrayWithObjects:#"friends_about_me", nil]];
[logInViewController setFields: PFLogInFieldsUsernameAndPassword | PFLogInFieldsLogInButton | PFLogInFieldsFacebook | PFLogInFieldsSignUpButton | PFLogInFieldsPasswordForgotten];
// Create the sign up view controller
PFSignUpViewController *signUpViewController = [[PFSignUpViewController alloc] init];
[signUpViewController setDelegate:self]; // Set ourselves as the delegate
// Assign our sign up controller to be displayed from the login controller
[logInViewController setSignUpController:signUpViewController];
// Present the log in view controller
[self presentViewController:logInViewController animated:YES completion:NULL];
} else {
[self performSegueWithIdentifier:#"login" sender:self];
}
}
Can you re-run your app with a breakpoint on the line of code in DefaultViewController.m
[logInViewController setDelegate:self]; // Set ourselves as the delegate
And in the identity inspector tell me what objects it contains?
I haven't had much experience with Parse, but it sounds like one of the frameworks may not be implemented properly. (if that's the case, it's a quick fix. you just re-download and put it back in your app)

Facebook and twitter login with Parse iOS only works once

I'm using the twitter and Facebook login in the Parse SDK. For every app launch I can log into each service once, but when I logout using [PFUser logOut] I am unable to log in again. The [PFFacebookUtils logInWithPermissions] block never gets called either with a user or an error.
My (Facebook) Login Code is:
- (IBAction)facebookLogin:(id)sender {
NSArray *permissionsArray = #[ #"user_about_me" ];
// Login PFUser using Facebook
[PFFacebookUtils logInWithPermissions:permissionsArray block:^(PFUser *user, NSError *error) {
if (!user) {
NSString *errorMessage = nil;
if (!error) {
NSLog(#"Uh oh. The user cancelled the Facebook login.");
errorMessage = #"Uh oh. The user cancelled the Facebook login.";
} else {
NSLog(#"Uh oh. An error occurred: %#", error);
errorMessage = [error localizedDescription];
}
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Log In Error"
message:errorMessage
delegate:nil
cancelButtonTitle:nil
otherButtonTitles:#"Dismiss", nil];
[alert show];
} else {
if (user.isNew) {
NSLog(#"User with facebook signed up and logged in!");
} else {
NSLog(#"User with facebook logged in!");
}
}
}];
}
My logout code is:
- (IBAction)loginButton:(id)sender {
if([PFUser currentUser]) {
[PFUser logOut];
NSLog(#"User is %#", [PFUser currentUser]);
NSLog(#"Facebook session is %#", [PFFacebookUtils session]);
NSLog(#"Facebook session is %#", FBSession.activeSession.observationInfo);
} else {
[self performSegueWithIdentifier:#"loginScreenSegue" sender:self];
}
}
Everything logs (null).
I assumed that as the behaviour was the same with Twitter, that it might be related to the OAuth related methods in my AppDelegate:
- (BOOL)application:(UIApplication *)application
openURL:(NSURL *)url
sourceApplication:(NSString *)sourceApplication
annotation:(id)annotation {
return [FBAppCall handleOpenURL:url
sourceApplication:sourceApplication
withSession:[PFFacebookUtils session]];
}
- (BOOL) application:(UIApplication *)application
handleOpenURL:(NSURL *)url
sourceApplication:(NSString *)sourceApplication
annotation:(id)annotation {
return [FBAppCall handleOpenURL:url
sourceApplication:sourceApplication
withSession:[PFFacebookUtils session]];
}
But have done a lot of research and don't seem to be missing anything...
I also have these in the AppDelegate:
- (void)applicationWillResignActive:(UIApplication *)application {
[[PFFacebookUtils session] close];
}
- (void)applicationWillTerminate:(UIApplication *)application {
[[PFFacebookUtils session] close];
}
- (void)applicationDidBecomeActive:(UIApplication *)application {
[FBAppCall handleDidBecomeActiveWithSession:[PFFacebookUtils session]];
}
Any help would be very gratefully received!
In you logout method, you should clear the Facebook session token as well like below:
[[FBSession activeSession]closeAndClearTokenInformation];
This will clear the active Facebook session's token.
OK, I finally solved this. The problem was that in my app setup on twitter, the permissions were set to 'Read only', not 'Read and Write'.
Changing this setting solved the problem with both facebook and twitter.

Not getting call to loginViewShowingLoggedInUser from FBLoginView

I am using the Facebook SDK for the first time. I am working with Xcode 5.1 and iOS 7.
I programmatically display FBLoginView:
- (void)viewDidLoad
{
[super viewDidLoad];
NSLog(#"viewDidLoad");
// Do any additional setup after loading the view.
if ( !loginView ) {
// loginView =[[FBLoginView alloc] initWithReadPermissions:#[#"basic_info"]];
loginView =[[FBLoginView alloc] initWithReadPermissions:[NSArray arrayWithObjects:#"basic_info", #"user_location", nil]];
}
loginView.delegate = self;
loginView.frame = CGRectOffset(loginView.frame,
(self.view.center.x -(loginView.frame.size.width /2)), 5);
CGPoint vCenter = CGPointMake( CGRectGetMidX(self.view.frame),
CGRectGetMidY(self.view.frame) );
CGPoint lvCenter = CGPointMake( vCenter.x, vCenter.y+100.0 );
loginView.center = lvCenter;
[self.view addSubview:loginView];
[self updateView];
}
I have implemented the required override functions:
#pragma mark - FBLoginViewDelegate
- (void) loginViewFetchedUserInfo:(FBLoginView *)loginView user:(id<FBGraphUser>)user {
NSLog(#"loginViewFetchedUserInfo");
[self updateView];
}
- (void) loginViewShowingLoggedInUser:(FBLoginView *)loginView {
NSLog(#"loginViewShowingLoggedInUser");
[self updateView];
}
- (void) loginViewShowingLoggedOutUser:(FBLoginView *)loginView {
NSLog(#"loginViewShowingLoggedOutUser");
[self updateView];
}
- (void)updateView {
NSLog(#"FB updateView");
[[FBRequest requestForMe] startWithCompletionHandler:
^(FBRequestConnection *connection, NSDictionary<FBGraphUser>*FBUser, NSError *error) {
if (error) {
NSLog(#"updateView - error");
} else {
NSLog(#"updateView - good");
NSNumber *owner_id = [NSNumber numberWithLong:[[FBUser id] longLongValue]];
if ( FB_user_id == nil ) {
FB_user_id = owner_id;
NSLog(#"FBUser ID = %#", FB_user_id);
loggedInSession = [FBSession activeSession];
[[NSUserDefaults standardUserDefaults] setObject:[FBUser id] forKey:#"eventOwnerID"];
[self performSegueWithIdentifier:#"continue_to_app" sender:self];
}
}
}];
if ([self checkFacebookSession]) {
}
dispatch_async(dispatch_get_main_queue(), ^{
[self.view setNeedsDisplay];
});
}
The FBLoginView button appears with "Log in with Facebook". I can log in and accept permissions, but the loginViewShowingLoggedInUser override function never gets called.
Someone suggested adding the following:
- (BOOL) application:(UIApplication *) application
openURL:(NSURL *)url
sourceApplication:(NSString *)sourceApplication
annotation:(id)annotation
{
NSLog ( #"application openURL");
NSLog ( #"URL = %#", url);
NSLog ( #"Application = %#", sourceApplication);
// Call FBAppCall's ha
BOOL wasHandled = [FBAppCall handleOpenURL:url sourceApplication:sourceApplication];
//[LoginUIViewController updateView];
return wasHandled;
}
This code had no effect and was never executed.
What am I doing wrong?
You are using #"basic_info", for this Facebook shows following error when I tried testing your code!
Invalid Scope: basic_info. Use public_profile, user_friends instead
I was interested in knowing where did you add the method:
- (BOOL) application:(UIApplication *) application
openURL:(NSURL *)url
sourceApplication:(NSString *)sourceApplication
annotation:(id)annotation
{
NSLog ( #"application openURL");
NSLog ( #"URL = %#", url);
NSLog ( #"Application = %#", sourceApplication);
// Call FBAppCall's ha
BOOL wasHandled = [FBAppCall handleOpenURL:url sourceApplication:sourceApplication];
//[LoginUIViewController updateView];
return wasHandled;
}
It should be in your AppDelegate, which works for me.
The read permissions have changed.
Refer this :
[https://developers.facebook.com/docs/apps/changelog#v2_0_permissions
][1]
The Error "invalide scope : basic info use public_profile, user friends instead" clearly states that "basic_info" is invalid and it suggests to make use of "public_profile" or "user_friends" as the new scope.
Change it in the following code:
self.loginView.readPermissions = #[#"basic_info"];
TO
self.loginView.readPermissions = #[#"public_profile"];

iOS Facebook SDK delegate methods not called

I see this question asked in several other posts but nothing seems to work for me. After following the FB login guide I had a working prototype that would allow users to authenticate with FB. However this guide instructs you place all FB OAuth logic directly into the AppDelegate and that is not ideal for me since I will support more than just FB authentication. So what I have done is move the login logic into it's own class. Since then it seems that the FB delegate methods do not get called after a user successfully authenticates with FB and control should be passed back to my application.
I have a modal login view which takes my FacebookAuth class as a delegate. When I attempt to create a session the FB login page appears and I authorize my application. After that no other delegate methods are called. Can anyone provide some hints?
#interface FacebookAuth()
#property (nonatomic, strong) User *sessionUser;
#end
#implementation FacebookAuth
#synthesize sessionIsOpen = _sessionIsOpen;
#synthesize sessionUser = _sessionUser;
-(id)initWithViewDelegate:(id<AuthorizationViewDelegate>)viewDelegate
{
NSAssert(viewDelegate != nil, #"FacebookAuth must be initialized with a view delegate.");
self = [super init];
if (self) {
self.viewDelegate = viewDelegate;
}
return self;
}
-(id)init
{
self = [super init];
if (self) {
self = [self initWithViewDelegate:nil];
}
return self;
}
-(BOOL)sessionIsOpen{
return (FBSession.activeSession.state == FBSessionStateOpen);
}
-(void)requestSessionUserWithSuccess:(void (^)(User *))success Failure:(void (^)(NSError *))error{
if(!self.sessionIsOpen){
error([NSError errorWithDomain:#"Session Closed" code:0 userInfo:nil]);
return;
}
if(self.sessionUser == nil){
[[FBRequest requestForMe] startWithCompletionHandler:
^(FBRequestConnection *connection,
NSDictionary<FBGraphUser> *user,
NSError *err) {
if (!err) {
User *ses_user = [[User alloc]initWithId:user.id first:user.first_name last:user.last_name sessionToken: [[[FBSession activeSession] accessTokenData] accessToken]];
self.sessionUser = ses_user;
success(ses_user);
} else{
error(err);
}
}];
} else{
success(self.sessionUser);
}
}
-(void)openSession
{
[FBSession openActiveSessionWithReadPermissions:nil
allowLoginUI:YES
completionHandler:
^(FBSession *session,
FBSessionState state, NSError *error) {
[self sessionStateChanged:session state:state error:error];
}];
}
-(void)closeSession{
[FBSession.activeSession closeAndClearTokenInformation];
self.sessionUser = nil;
self.sessionIsOpen = NO;
};
-(void)sessionStateChanged:(FBSession *)session
state:(FBSessionState) state
error:(NSError *)error
{
switch (state) {
case FBSessionStateOpen:{
self.sessionIsOpen = YES;
[self.viewDelegate loginSuccess];
}
break;
case FBSessionStateClosed:{
self.sessionIsOpen = NO;
}
break;
case FBSessionStateClosedLoginFailed:{
[FBSession.activeSession closeAndClearTokenInformation];
self.sessionIsOpen = NO;
[self.viewDelegate loginFailure:error];
}
break;
default:
break;
}
}
-(BOOL)application:(UIApplication *)application
openURL:(NSURL *)url
sourceApplication:(NSString *)sourceApplication
annotation:(id)annotation
{
return [FBSession.activeSession handleOpenURL:url];
}
I apologize for the large code snippet but I don't want to leave out anything that may be valuable in assisting.
After calling
-(void)openSession:
The facebook authentication page appears and I authorize the application. After that I was expecting the FB delegate method to be called:
-(BOOL)application:(UIApplication *)application
openURL:(NSURL *)url
sourceApplication:(NSString *)sourceApplication
annotation:(id)annotation
It never is. Do I need to declare this class as a type of FB delegate? I am using the latest Facebook SDK available.
Any help would be great.

Resources