When attempting to login to facebook in my app, I am experiencing a few strange behaviors.
Current stack information:
- Appcelerator 6.0.1.GA
- Appcelerator CLI 6.1.0
- iOS 10.1
- xCode 8.2.1
Strange Behaviors:
login
event never fires when returning from Facebook login on device.login
event sometimes doesn't fire when returning from Facebook login on simulator.- Setting facebook.LOGIN_BEHAVIOR_NATIVE still attempts to use browser login on device, sometimes.
- Sometimes on device, the app-switcher opens the Facebook app and the browser for login. This is quite vexing.
I'm actually the original contributor of the setLoginBehavior
functionality of the module, though Facebook's stance seems to have changed since that contribution from "We always want you to use browser." to "We always want you to use Native.". I'm posting this question here in case someone has some insight - while I wait for an answer I will be back into the source for that module.
The only factor that I can imagine might be different from most apps is that I am using Kris Kowals Q. Here follows the code, almost verbatim from my app.
The actual function that does the login:
// linkingmodule.js
exports.linkFacebook = function() {
var Q = require('vendor/q'),
response = Q.defer(),
facebook = require('facebook'),
permissions = ['public_profile', 'user_friends', 'user_likes'];
facebook.initialize();
facebook.setLoginBehavior(facebook.LOGIN_BEHAVIOR_NATIVE);
facebook.permissions = permissions;
facebook.addEventListener('login', function fireLogin(e) {
if(!e.success || !facebook.loggedIn) {
return response.reject({
status: e.code,
error: e.error
});
}
response.resolve({
uid: e.uid,
data: e.data,
token: facebook.getAccessToken()
});
});
facebook.authorize();
return response.promise;
};
The alloy controller function that calls the login function:
// login.js
function facebookLogin() {
var remote = require('linkingmodule');
remote.linkFacebook().
then(function(r) {
// do some things
}).
fail(function(e) {
console.error(e);
throw 'Unable to login with Facebook.';
});
}).
fail(function(e) {
console.error('Facebook login failed');
console.error(e);
});
}
I have chalked this up to a bug in the Titanium module SDK, specifically
Ti.fireEvent
. My investigation ended with the Facebook Module, but all events within the module appeared to be sent and received as expected. Only, whenTi.fireEvent
was called, it was not received in the JS app "under some circumstances". The possibility remains of a block retain cycle within the facebook module, but I was not able to solve it.Here is my workaround:
So, basically keep listening for the
login
event - it fires correctly under "some circumstances". But also listen forApp.resumed
. Whichever fires first, cancel all listeners, and check for logged in status.