4

EDIT: DEAR PEOPLE FROM THE FUTURE, trey-jones has fixed this issue by implementing setLoginBehavior, FBSDKLoginNative seems to have issues on FB's end not with the module.

Environment:

MacOS X 10.10.5
Ti SDK 5.1.1.GA - 5.1.2.GA
iOS 9.2
Ti.Facebook 5.0.0 - 5.0.1

My project settings (tiapp.xml) are fine (it works on every other case on both iOS and Android).

Code I'm using to invoke the login:

var fb = require('facebook');
fb.initialize();
fb.authorize(); 

If the Facebook app is installed to the device the fb.authorize() doesn't open up. I did not see any iOS system level messages when this happened either.

Has anyone else had luck using fb.authorize with the new sdk on iOS devices WITH the app installed. With no fb app on the system it correctly opens the browser based view.

EDIT: I have managed a workaround for this (it is not pretty) based on the fact that login works with AppC's KitchenSink.

The workaround is to add a Ti.FB loginButton to the code, doesn't matter if its not visible, initializing this will fix whatever is causing custom login's .authorize() to not work.

//Workaround button:
if(OS_IOS){
    var fbHaxBtn = fb.createLoginButton({
        readPermissions: ['email'],
        visible: false
    });
}
//It needs to be added to the window/doesn't need to be visible though
$.login_window.add(fbHaxBtn);

//Then in our custom button's code, we can fire as normal:
function doLoginClick{
    fb.initialize(); //I was having unexpected issues dropping this line on Android, although the docs say its deprecated.
    fb.authorize();
}

Will keep this ticket updated if/when this thing gets a formal fix.

boarnoah
  • 139
  • 2
  • 8
  • 1
    Excellent find, have been struggling with this for days! Also worth a mention that on Android fb.initialize() is not working for me unless I add a timeout to it: i.e. fb.initialize(5000); – Martyn Joyce Mar 04 '16 at 16:46
  • 1
    Thank you for posting this. If there is one thing I was reminded trying to use the FB module, it's not to trust the appc docs. I had the same situation, but I didn't need to add the button. I was not calling `initialize`, and adding that line allowed authorize to function as before. More strangely, once I removed the `initialize` call, it continued to function. Lately I'm wondering whether developing in titanium is actually faster than native... – trey-jones Mar 15 '16 at 14:38

2 Answers2

1

EDIT: This answer does not solve the original question. I have left it here in case it helps with related difficulties using the Ti.Facebook module. See my other answer, to actually solve the problem. END EDIT

I commented above, but after doing so encountered some more strange behavior, with the result being that I could not reliably use the workaround given (fbHaxButton). I want to explain what was happening in my case, and show my own workaround (which is also not pretty). It's possible that the root cause is the same for both of us.

I have not bothered with Android yet, so this answer is specific to iOS.

When I started this process, I came to the conclusion that authorize was correctly opening the facebook website in safari to allow authorization, but was not firing the login event upon returning. To handle this I had already implemented the following:

facebook = require('facebook');

Ti.App.addEventListener('resumed', function (e) {
    var launchOptions = Ti.App.getArguments();
    if(!launchOptions.url) {
        return console.warn('Ignoring resume event with no url argument.');
    }

    // this lib = https://github.com/garycourt/uri-js
    var URI = require('vendor/uri'),
        uriComponents = URI.parse(launchOptions.url),
        expectedScheme = 'fb',
        expectedHost = 'authorize';

    // I would like to be more specific about the uri, but we are limited 
    // in Titanium, and this will allow us to pretty certain 
    // that FB is sending us back to our app
    if(uriComponents.scheme.search(expectedScheme) < 0 || uriComponents.host !== expectedHost) {
        return console.warn('Resume event received, but scheme is incorrect.  Ignoring.');
    }

    // synthesize login event
    facebook.fireEvent('myapp:login', {
        success: 1,
        token: facebook.getAccessToken(),
        uid: result.id
    });
});

facebook.addEventListener('myapp:login', function onFacebookAuth(e) {
    facebook.removeEventListener('myapp:login', onFacebookAuth);
    if(!e.success) {
    // do fail action
    }
    // do success action
});

facebook.initialize(); 
facebook.authorize();

So, originally I was firing and listening for an event called 'login', which the facebook module supposedly (according to the docs) will fire after authorization is complete.

In my case, this event was being fired while my app was in the background, after authorize was called, but before the user actually clicked 'OK' in facebook. My listener would respond to this event (logging, etc), but seemed to occur in a separate thread, or somehow otherwise become disconnected from my app, as it never passed its result along to the UI. I am using Q.js (kriw-kowal) and I belive this is where the disconnect is occuring.

Ceasing to listen to 'login', and simply handling my own synthesized event has fixed my issue.

I felt that this was very difficult to explain. If you have feedback about that, and how I can be more clear about what I believe is happening, or if you believe that I have reached wrong or incomplete conclusion, let me know - I'll try to update this answer to be better.

trey-jones
  • 3,329
  • 1
  • 27
  • 35
1

This is my second answer on this question. I believe that my original answer offers some value to the conversation and that is why I am leaving it, but it still did not consistently solve the problem of the facebook authorization not working.

The consistent solution turned out to be modifying the official Ti.Facebook module. I will submit a pull request for this change (1 line), but for now, you can get the working module here:

Source

Pre-built

This consistently allows users to authorize by explicitly setting the login behavior to use the browser, rather than the native facebook app through fast app-switching. This is actually the intent of Facebook's developers.

I was unable to determine what is causing it to fizzle when trying to use the native app to login - it should try the next option, which is the browser - but this works, and doesn't require a TiFacebookButton either.

I hope it helps someone else!

trey-jones
  • 3,329
  • 1
  • 27
  • 35
  • Aah, I commented on the pull request without realising it was you. Also sent AppC a link to the pr on the salesforce ticket hopefully they will have a look at it soon. Thanks again. – boarnoah Mar 26 '16 at 02:00
  • Thanks for trying to help it through. Seems important! – trey-jones Mar 26 '16 at 02:30