Error in FB.login() phonegap facebook plugin - ios

When i run fb.login() in an ios 6 device using the account setted in Settings/facebook i get the following
operation couldn't be completed (com.facebook.sdk error 2)
in ios 5 the app works perfectly, the problem is the native login
help please ! this is my code
this is the facebook init
this.appId = appId;
var me = this;
document.addEventListener('deviceready', function() {
try {
FB.init({ appId: "294003447379425", status: true, cookie: true, nativeInterface: CDV.FB, useCachedDialogs: false });
} catch (e) {
console.log(e);
}
}, false);
if (!this.appId) {
Ext.Logger.error('No Facebook Application ID set.');
return;
}
var me = this;
me.hasCheckedStatus = false;
FB.Event.subscribe('auth.logout', function() {
// This event can be fired as soon as the page loads which may cause undesired behaviour, so we wait
// until after we've specifically checked the login status.
if (me.hasCheckedStatus) {
me.fireEvent('logout');
}
});
// Get the user login status from Facebook.
FB.getLoginStatus(function(response) {
me.fireEvent('loginStatus');
clearTimeout(me.fbLoginTimeout);
me.hasCheckedStatus = true;
if (response.status == 'connected') {
me.fireEvent('connected');
Ext.Viewport.add(Ext.create('CinePass.view.Main'));
} else {
me.fireEvent('unauthorized');
console.log('noconectado');
Ext.Viewport.add(Ext.create('CinePass.view.LoggedOut'));
}
});
// We set a timeout in case there is no response from the Facebook `init` method. This often happens if the
// Facebook application is incorrectly configured (for example if the browser URL does not match the one
// configured on the Facebook app.)
me.fbLoginTimeout = setTimeout(function() {
me.fireEvent('loginStatus');
me.fireEvent('exception', {
type: 'timeout',
msg: 'The request to Facebook timed out.'
});
Ext.Msg.alert('CinePass', 'Existe un problema con Facebook, se iniciará la aplicación sin conexión a Facebook.', Ext.emptyFn);
Ext.Viewport.add(Ext.create('CinePass.view.Main'));
}, me.fbTimeout);
this is the login
FB.login(
function(response) {
if (response.session) {
alert(response.session);
} else {
alert(response.session);
}
},
{ scope: "email,user_about_me,user_activities,user_birthday,user_hometown,user_interests,user_likes,user_location,friends_interests" }
);

Having the same problem and took me few days to figure this out, there are a number of reasons:
1) The first time you launch your app, if you deny the "Do you allow this app to use your facebook permission", you'll get this error, what you need to do is, go to Setting > General > Facebook > turn on your app OR go to Setting > General > Reset > Reset Location & Privacy (this will reset and ask you the "Do you allow this app to use your facebook permission" again for all app.
2) Slow/No Internet can caused the error
3) Create your certificate again, and go to build.phonegap.com, create a new key for IOS and change the IOS key (This works for me, I have no idea how it works but it does, I notice a significant app file size increase after i use a new IOS Key)
4) If your app is in sand box mode, and your IOS current Facebook account is not an app tester you'll get the error too. I just disable the sand box mode and it works, make sure your Facebook App Setting has the correct bundle ID, if your app is still under developement, put 0 to app store ID.

Related

How to share cookies between in-app browser and React Native (iOS)?

I am trying to implement SSO in a mobile app.
I am using react-native-inappbrowser-reborn to handle the SSO auth flow in an in-app browser. I can successfully authenticate inside the in-app browser. That is to say, I receive a session cookie and I can view the web version of the app from inside of the in-app browser. However, when I redirect back to the mobile application, none of my fetch requests include the session cookie! I have fetch configured with {credentials: 'include'}. CookieManager.getAll() returns an empty object.
I am experiencing this problem on iOS (v15.2), and I have yet to test on Android.
According to the documentation I should be able to share the cookie set in the in the in-app browser with my react-native app.
I am using the following code based off of the react-native-inappbrowser-reborn documentation
async function authenticate() {
const url = 'http://localhost:3000/sso/login?redirect_uri=myapp://home';
const deepLink = 'myapp://home';
try {
if (await InAppBrowser.isAvailable()) {
InAppBrowser.openAuth(url, deepLink, {
// iOS Properties
ephemeralWebSession: false,
// Android Properties
showTitle: false,
enableUrlBarHiding: true,
enableDefaultShare: false,
}).then(async (response) => {
if (response.type === 'success' && response.url) {
console.log('should see a new cookie set!');
console.log(await CookieManager.getAll()); // Sadly, nothing in here
const user = await fetch('http://localhost:3000/user', {
credentials: 'include',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
},
});
/* This is an authenticated endpoint which returns a 401,
because for some reason the session cookie doesn't go along with the request */
}
});
} else {
throw new Error('login unsuccessful');
}
} catch (error) {
throw new Error();
}
}
Any bit of insight here would be immensely appreciated!

Cordova/Ionic IAP not always works

I have made my Cordova/Ionic app with in app purchases. During test period all works fine, published it live in Google Play and App Store all seems to be fine. Get lots of purchases, tested it myself on different devices and all seems ok. But then after a week the first email came in they purchases an IAP and it was not unlocked (iOS, have any issues heared from Android users). Tow weeks later a second... now I have like 15 people where is does not work and I have seen prove that they have purchased it.
I am using this IAP plugin:
https://github.com/AlexDisler/cordova-plugin-inapppurchase
Before that one I used another IAP plugin, but because of the same problem I started to use the first one:
https://github.com/j3k0/cordova-plugin-purchase
I also made a issue post on github but still no answer:
As I am not allowed to post more links atm, it is issue 113.
The code I use works in 99.9%:
loadProducts = function () {
$ionicLoading.show({ template: spinner + 'Loading...' });
inAppPurchase
.getProducts(productIds)
.then(function (products) {
$ionicLoading.hide();
// Load all products by ID
products.forEach(function (product) {
// Add extra field to the product object
product.owned = false;
switch (product.productId) {
case ncProductProVer:
if (GlobalVars.vars.fullVersion == true) {
product.owned = true;
}
break;
case ncProductNoAds:
if (GlobalVars.vars.noAds == true) {
product.owned = true;
}
break;
}
});
//alert(products[0].productId + ' ' + products[1].productId);
$scope.products = products;
})
.catch(function (err) {
$ionicLoading.hide();
//$cordovaDialogs.alert('Error loading products. Details:\n- Code: ' + err.code + '\n- Message: ' + err.message, 'Error', 'OK')
$scope.CodeError = true;
});
};
// BUY a product
$scope.buy = function (productId) {
$ionicLoading.show({ template: spinner + 'Buying...' });
inAppPurchase
.buy(productId)
.then(function (data) {
$ionicLoading.hide();
enableIAP(productId, true);
})
.then(function () {
$ionicLoading.hide();
loadProducts();
})
.catch(function (err) {
$ionicLoading.hide();
errHandling(err.code, productId);
});
};
// RESTORE in app purchases
$scope.restore = function () {
$ionicLoading.show({ template: spinner + 'Restoring purchases...' });
inAppPurchase
.restorePurchases()
.then(function (purchases) {
$ionicLoading.hide();
purchases.forEach(function (purchase) {
// Unlock the relevant feature based on this product id, if any
// Store the purchase in localStorage
enableIAP(purchase.productId, true);
});
// Reload the productlist
loadProducts();
})
.catch(function (err) {
$ionicLoading.hide();
});
};
I have tried many different things already, but cant figure out what the problem can be or how I can see what goes wrong as the app runs on a device where I don't have access to :).
The only thing I have is that people say the 'Buying...' popup keeps on loading till they close the app and run it again. So the problem must me in the .buy() function and does not give a error back but otherwise it will be in the .catch().
Things I can think of is:
- Apple does not always sends the same string back
- The string send back from Apple contains chars that are not correctly handled by the IAP code
To make things more odd, I managed to get in contact with somebody where it did not work. So I started testing some things as I thought maybe it could be device settings. So I had the iPhone and signed in with my iTunes account, downloaded the app and restored the IAP and it worked. Did the same thing, sign in with their iTunes account, did not work. That person also had an iPad mini, where it all worked as expected, the extra item in the app where unlocked as they should.
Anybody seen this strange behaviour? Been busy many weeks/months already to figure out what it could be.

Potential causes of Ionic function not working in Ionic View, but working on web

I am building a food delivery app using Ionic. And I am having problems getting the app to work on mobile for the address creation step. After creating an account the user must create a delivery address, at which point the app figures out what delivery location to use.
Address creation works in Chrome (ionic serve) and in iOS simulator (ionic run ios -l -c -s).
However, once I've uploaded the app to my Ionic View iOS app for testing, it gets stuck at the Address creation step.
But at the address creation step, the Ionic loading wheel starts but it doesn't go away and there is no state transition to the menu.
Here is the implementation in the controller.
Address.create($scope.newAddress, $scope.user)
.then(function(response) { // never gets a response back in Ionic View
console.log("address created");
user.save(null,
{ success: function(user) {
// success callback
}, error: function(error) {
// throw error
}
});
}, function(error) {
// throw error
});
The Address.create() method I have implemented is fairly lengthy:
...
.factory('Address', ['$http', '$q', 'PARSE_HEADERS'
function ($http, $q, PARSE_HEADERS) {
return {
create: function(data, userID) {
var deferred = $q.defer();
var zipArray = ['1111','22222','33333'];
var inZone = false;
var restaurantCoords = {
latitude: 11.11111, longitude: 22.22222
};
for (var i=0, bLen=zipBrooklyn.length; i<bLen; i++) {
if(data.zipCode==zipArray[i]) {
inZone = true;
}
}
if (inZone == true ) { // valid zip
function onSuccess(coords) {
var limit = 3041.66;
var meters = getDistance(coords, restaurantCoords);
if (meters < limit) {
$http.post('https://api.parse.com/1/classes/Address', data, {
headers: PARSE_HEADERS
})
.success(function(addressData) {
deferred.resolve(addressData);
})
.error(function(error, addressData) {
deferred.reject(error);
});
}
function onError() {
deferred.reject("Unable to Geocode the coordinates");
}
// GET COORDS
navigator.geocoder.geocodeString(onSuccess, onError, data.address1 + ',' + data.zipCode);
}
}
return deferred.promise;
}]);
I've stripped out all of the code that I believe was working.
So a valid answer for this question could take multiple forms:
I'd accept an answer giving a decent way to debug apps IN Ionic View.
Or, if someone could provide an answer as to why it might be working in the browser and in iOS Simulator, but not iOS itself, that would be appreciated even more.
Ionic view doesn't support all the plugins yet. please take a look at this link for the list of supported plugins.
Device is always better (First Option). If you have a ios device and apple developer account. You can create and configure the required certificate with the device id and run the app using 'ionic run ios'. Second option is iOS simulator. You can use the simulator for your whole app, though few tasks would need a device.
Even if you use the simulator for the whole development, it is always advisable to test in the device before launcing the app.

Cordova/Ionic Facebook getLoginStatus not working

I am developing an App in Ionic/Cordova with Login over Facebook. Before showing the "Login-Page" I would like to check if the user is already connected.
The following getLoginStatus check works as expected in the iOS Simulator. When testing on the actual device, the getLoginStatus callback does not get fired.
facebookConnectPlugin.getLoginStatus(
function (response) {
if (response.status == "connected") {
set_tokens(response);
$location.path('/tab/person/me/events');
}
},
function (response) { alert(JSON.stringify(response)) }
);
Already set the Facebook-App to public and verified the App-Id.
Can anybody give a reason for the described behaviour?
I have the following implementation for Facebook login using facebookConnect Plugin.
facebookConnectPlugin.getLoginStatus(
function(response){
if(response.status == "connected"){
//do something, for example share or redirect
}else{
facebookConnectPlugin.login(["basic_info"],
function(success) { /*do something...*/},
function(error) {
//handle error
});
}
}, function(error) {
// handle error
})
}
If you still have errors, try to log the error and success events to see what is happening. This implementations works in a controller.

Ask for location access after initial rejection in PhoneGap apps

I'm developing cross platform applications. I'm able to request access to location using the Phone Gap API. If the user clicks okay, then I'm able to get the latitude and longitude using PhoneGap API and send it to the server.
However, I'm facing issues if the user clicks "Don't Allow" initially. After that, if he tries to refresh page, I want the device to show the popup again to request access to the location.
How do we do that in Single Page Applications?
var loadPanelMessage = ko.observable("Sipping..."),
loadPanelVisible = ko.observable(false),
lat = ko.observable(''),
lon = ko.observable('');
navigator.geolocation.getCurrentPosition(onSuccess, onError);
var onSuccess = function (position) {
lat(position.coords.latitude);
lon(position.coords.longitude);
timestamp(position.timestamp);
};
function onError(error) {
alert('code: ' + error.code + '\n' +
'message: ' + error.message + '\n');
//How should I handle the error, so that it asks for Geolocation again?
}
You cannot reshow that popup, it is shown by iOS and once user click's "Don't Allow" you cannot force that popup. All you can do is to let your user know about the situation and direct the user to iOS settings to enable location services for your app.
Here is a nice read about the problem:
https://medium.com/on-startups/96fa4eb54f2c
Based on the cordova plugins here org.apache.cordova.geolocation
All you need to do is a watchPosition to check the PositionError, and use also the cordova-plugin-dialogs to show the native notification
navigator.geolocation.watchPosition((function(_this) {
return function(position) {
// Do something here
};
})(this), function(error) {
var errorButton, errorMsg, errorTitle;
errorTitle = "Location Services";
errorButton = "Ok";
if (error.code === 1) {
errorMsg = "\"AppName\" needs access to your location. Please turn on Location Services in your device settings.";
}
if (error.code === 2) {
errorMsg = "This device is unable to retrieve a position. Make sure you are connected to a network";
}
if (error.code === 3) {
errorMsg = "This device is unable to retrieve a position. Make sure you have Location Services enabled for \"AppName\"";
}
if (error.code === 1 || error.code === 2 || error.code === 3) {
return navigator.notification.alert(errorMsg, errorDismissed(), errorTitle, errorButton);
}
}, {
enableHighAccuracy: true,
maximumAge: 20000,
timeout: 10000
});

Resources