I am using FirebaseSimpleLogin for authenticating my app via facebook.
I have updated .plist file with facebookapp id and display name. I have also registered bundle id of my app.
As suggested in docs, i have also implemented openUrl in AppDelegate and following method in my login with Facebook button. But console is showing third party provider error occurred. Anyone have any clue??
- ( IBAction ) onBtnFacebook : ( id ) sender {
[self.authClient loginToFacebookAppWithId:#"767056019984823" permissions:#[#"email"] audience:ACFacebookAudienceOnlyMe withCompletionBlock:^(NSError *error, FAUser *user) {
if (error != nil) {
NSLog(#"%#",error);
UIAlertView *message = [[UIAlertView alloc] initWithTitle:#""
message:#"There was an error in opening your account. Please try again."
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[message show];
} else {
UIAlertView *message = [[UIAlertView alloc] initWithTitle:#"Welcome"
message:self.email
delegate:nil
cancelButtonTitle:#""
otherButtonTitles:nil];
[message show];
[ self dismissViewControllerAnimated : YES completion : ^{
} ] ;
}
}];
}
In Appdelegate.m
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation {
BOOL wasHandled = [FBAppCall handleOpenURL:url sourceApplication:sourceApplication];
NSLog(#"hello");
// add any app-specific handling code here
return wasHandled;
}
Related
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.
When I authenticate within the iPhone Simulater in debug mode the first if statement in the code below is run. However, when I debug on an iPhone that has the Evernote client installed the if statement does not appear evaluated. Instead the Evernote iOS app comes up for just a moment, then straight back to this ViewController without hitting any set breakpoints below the if, or the segue being fired.
Any ideas?
[session authenticateWithViewController:self completionHandler:^(NSError *error) {
if (error || !session.isAuthenticated){
if (error) {
NSLog(#"Error authenticating with Evernote Cloud API: %#", error);
}
if (!session.isAuthenticated) {
NSLog(#"Session not authenticated");
}
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Error"
message:#"Could not authenticate"
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[alert show];
} else {
// We're authenticated!
EvernoteUserStore *userStore = [EvernoteUserStore userStore];
[userStore getUserWithSuccess:^(EDAMUser *user) {
// success
NSLog(#"Authenticated as %#", [user username]);
[self performSegueWithIdentifier:#"introductionStepOne" sender:self];
} failure:^(NSError *error) {
// failure
NSLog(#"Error getting user: %#", error);
} ];
}
}];
Make sure you modify your AppDelegate properly. More information here : https://github.com/evernote/evernote-sdk-ios#modify-your-appdelegate
You need to add :
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication: (NSString *)sourceApplication annotation:(id)annotation {
BOOL canHandle = NO;
if ([[NSString stringWithFormat:#"en-%#", [[EvernoteSession sharedSession] consumerKey]] isEqualToString:[url scheme]] == YES) {
canHandle = [[EvernoteSession sharedSession] canHandleOpenURL:url];
}
return canHandle;
}
And
- (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.
[[EvernoteSession sharedSession] handleDidBecomeActive];
}
I am using sdk 3.1 and trying to use the friendpickercontroller but for somehow table is loading empty on my app.
This is my code, can you give hints on the reason?
Thanks
- (void) loadFacebookFriendsPicker:(UINavigationController *)senderNavigationController {
if (!FBSession.activeSession.isOpen) {
// if the session is closed, then we open it here, and establish a handler for state changes
[FBSession.activeSession openWithCompletionHandler:^(FBSession *session,
FBSessionState state,
NSError *error) {
switch (state) {
case FBSessionStateClosedLoginFailed:
{
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:#"Error"
message:error.localizedDescription
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[alertView show];
}
break;
default:
break;
}
}];
}
if (self.friendPickerController == nil) {
// Create friend picker, and get data loaded into it.
self.friendPickerController = [[FBFriendPickerViewController alloc] init];
self.friendPickerController.title = #"Pick Friends";
self.friendPickerController.delegate = self;
}
[self.friendPickerController loadData];
[self.friendPickerController clearSelection];
[senderNavigationController pushViewController:self.friendPickerController animated:YES];
}
Shouldn't your friendPickerController be in the completion handler? The way you're doing it now, friendPickerController would be nil when you'd access it because the completion handler executes asynchronously.
Move your friendPickerController login into the switch case block with condition FBSessionStateOpen. Something like this:
switch (state) {
case FBSessionStateOpen: {
if (self.friendPickerController == nil) {
// Create friend picker, and get data loaded into it.
self.friendPickerController = [[FBFriendPickerViewController alloc] init];
self.friendPickerController.title = #"Pick Friends";
self.friendPickerController.delegate = self;
}
[self.friendPickerController loadData];
[self.friendPickerController clearSelection];
[senderNavigationController pushViewController:self.friendPickerController animated:YES];
}
(Not sure about calling pushViewController here though)
You probably need to have this function in your app Delegate
// FBSample logic
// In the login workflow, the Facebook native application, or Safari will transition back to
// this applicaiton via a url following the scheme fb[app id]://; the call to handleOpenURL
// below captures the token, in the case of success, on behalf of the FBSession object
- (BOOL)application:(UIApplication *)application
openURL:(NSURL *)url
sourceApplication:(NSString *)sourceApplication
annotation:(id)annotation {
return [FBAppCall handleOpenURL:url sourceApplication:sourceApplication];
}
I am logging in into facebook in this way:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
[FBSession openActiveSessionWithReadPermissions:nil
allowLoginUI:YES
completionHandler:
^(FBSession *session,
FBSessionState state, NSError *error) {
[self sessionStateChanged:session state:state error:error];
}];
return YES;
}
- (void)sessionStateChanged:(FBSession *)session
state:(FBSessionState) state
error:(NSError *)error
{
switch (state) {
case FBSessionStateOpen:
if (!error) {
// We have a valid session
//NSLog(#"User session found");
// Initiate a Facebook instance
self.facebook = [[Facebook alloc]
initWithAppId:FBSession.activeSession.appID
andDelegate:nil];
// Store the Facebook session information
self.facebook.accessToken = FBSession.activeSession.accessToken;
self.facebook.expirationDate = FBSession.activeSession.expirationDate;
}
break;
case FBSessionStateClosed:
case FBSessionStateClosedLoginFailed:
[FBSession.activeSession closeAndClearTokenInformation];
// Clear out the Facebook instance
self.facebook = nil;
break;
default:
break;
}
if (error) {
UIAlertView *alertView = [[UIAlertView alloc]
initWithTitle:#"Error"
message:error.localizedDescription
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[alertView show];
}
}
- (BOOL)application:(UIApplication *)application
openURL:(NSURL *)url
sourceApplication:(NSString *)sourceApplication
annotation:(id)annotation {
// attempt to extract a token from the url
self.openedURL = url;
// attempt to extract a token from the url
return [FBSession.activeSession handleOpenURL:url];
}
...and I get the error: Error: HTTP status code: 400
I have set up the URL scheme in the plist. Why am I getting this?
Check in the App Dashboard. Look at your Basic Settings. Your Sandbox Mode may be set to Enabled. The errors should go away when your app is out of Sandbox mode.
I'm using the FB iOS SDK to get the user's credentials and access token and save them. With the previous version I managed to properly do this, but my solution broke with the upgrade to iOS 6, so I downloaded the new version from Github, and compiled and added the framework to my project according to the instructions.
I properly authenticate my user with FB, but when the browser (the modal view controller presented for auth) is dismissed my user reverts to the initial view of my app instead of the view that the process was launched from.
Right now I have code in my app delegate and my SocialNetworksViewController to do this.
In AppDelegate:
-(BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation {
return [FBSession.activeSession handleOpenURL:url];
}
- (void)sessionStateChanged:(FBSession *)session
presentingViewController:(UIViewController *)presentingViewController
state:(FBSessionState) state
error:(NSError *)error
{
switch (state) {
case FBSessionStateOpen: {
[presentingViewController dismissModalViewControllerAnimated:YES];
}
break;
case FBSessionStateClosed:
case FBSessionStateClosedLoginFailed:
// Once the user has logged in, we want them to
// be looking at the root view.
[FBSession.activeSession closeAndClearTokenInformation];
break;
default:
break;
}
[[NSNotificationCenter defaultCenter] postNotificationName:FBSessionStateChangedNotification
object:session];
if (error) {
UIAlertView *alertView = [[UIAlertView alloc]
initWithTitle:#"Error"
message:error.localizedDescription
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[alertView show];
}
}
- (void)openSessionFromViewController:(UIViewController *)viewController
{
NSArray *permissions = [NSArray arrayWithObjects:#"publish_stream", #"email", #"user_birthday", nil];
[FBSession openActiveSessionWithPermissions:permissions
allowLoginUI:YES
completionHandler:
^(FBSession *session,
FBSessionState state, NSError *error) {
[self sessionStateChanged:session presentingViewController:viewController state:state error:error];
}];
}
In SocialNetworksViewController:
- (IBAction)connectToFacebook:(UIButton *)sender {
if (!self.facebookConnected) {
AppDelegate <UIApplicationDelegate> *appDelegate = (AppDelegate *)[UIApplication sharedApplication].delegate;
[appDelegate openSessionFromViewController:self];
}
}
- (void)sessionStateChanged:(NSNotification*)notification {
NSLog(#"%#", FBSession.activeSession.accessToken);
}
- (void)facebookLoginFailed {
}
This is in viewDidLoad as well:
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(sessionStateChanged:)
name:FBSessionStateChangedNotification
object:nil];
In the sessionStateChanged method, the NSLog outputs and then I get send to my initial view.