简体   繁体   中英

Ti.Facebook doesn't open authorize with FB app installed

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.

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.

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!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM