Ionic 2 Native Facebook Plugin errors when grabbing User profile picture - facebook-graph-api

I have a snippet of code in my Ionic 2 app that is supposed to grab the Facebook profile of the user after they have successfully logged on. I've verified that the request path /me returns data associated with the user, however when I set the request path to /me/picture, I get an error: There was an error making the graph call.
Here is my code:
if(this.platform.is('cordova')) {
Facebook.login([
'public_profile',
'user_friends',
'email'
]).then((result) => {
Facebook.api('/me?fields=id,name,email,cover', []).then(data => {
// Create the user object
let user = {
access_token: result.authResponse.accessToken,
display_name: data.name,
email: data.email,
facebook_id: data.id,
cover_photo: data.cover.source,
}
Facebook.api(`me/picture`, []).then(data => {
user['profile_photo'] = data.url;
this.loginWithFacebook(user);
}, error => { this.user = JSON.stringify(error)});
})
},
error => {
this.user = JSON.stringify(error);
})
}
Am I missing something? I've even tried doing /{user-id}/picture and still receive an error. Anyone run into this issue?

By default this edge will return a 302 redirect to the picture image. To get access to the data about the picture, please include redirect=false in your query.
Source: https://developers.facebook.com/docs/graph-api/reference/user/picture/
For example: Facebook.api('me/picture?redirect=false', [])...

Related

Sequelize model only updates when I log out then log back in

So basically my issue is that when a user is logged in they can take a test. When the test is passed a user is given points and their level is updated using a put route. Once the put route has run the user is redirected back to their homepage where their stats are displayed. If I look in Postman after the request is made I can see the changes. However, the get route on the user's homepage is still displaying as the previous data. Only when I log out then log back in does the user object actually update on the app.
the get request is called in the document. ready function for the user's page like so...
$(document).ready(() => {
// This file just does a GET request to figure out which user is logged in
// and updates the HTML on the page
$.get("/api/user_data").then(data => {
console.log(data)
$(".user-name").text(data.username);
$(".first-name").text(data.first);
$(".last-name").text(data.last);
$(".email").text(data.email);
$(".xp").text(data.points);
});
the put route is in a function that runs when the last question of the test is answered. It looks like this...
function endGame() {
console.log("END OF GAME SCORE: " + score);
$(".quiz-container").css("display", "none");
console.log(data.points);
console.log(data.level);
var addPoints = score * 100 + data.points;
var newLevel = data.level + 1;
$.ajax({
url: "/api/user_data",
method: "PUT",
data: {
id: data.id,
level: newLevel,
point: addPoints
},
error: function(req, err) {
console.log(err)
},
success: function(res, err) {
window.location.replace("/members");
}
}).then(result => {
console.log("user info updated");
console.log(result);
window.location.replace("/members");
});
}
As you can see the user is redirected over to the "members" page which is where the get request is sent on the document being ready. I'm pretty new so any help would be greatly appreciated.
also here is the db.sync method I had been working with force true and force false now i just have...
db.sequelize.sync({}).then(() => {
app.listen(PORT, () => {
console.log(
"==> 🌎 Listening on port %s. Visit http://localhost:%s/ in your browser.",
PORT,
PORT
);
});
});

How to handle login errors with Ionic custom auth?

I'm trying to implement a user login with Ionic Cloud's Auth Service, and would prefer to no show the Cordova inAppBrowser. In case of an authentication error (e.g. wrong password), I would expect the error handler to fire, but for some reason this never seems to be the case.
The method in my login component contains this:
let loginData = {
email: this.email,
password: this.password
};
let loginOptions: AuthLoginOptions = {
inAppBrowserOptions: {
hidden: true
}
};
this.auth.login('custom', loginData, loginOptions).then(() => {
console.log('login success');
}, (err) => {
console.log('login error', err); // <-- this never gets executed.
});
I made sure that my authentication server responds with an HTTP status of 401 and a JSON body that contains an error property. This is the code (PHP, Laravel 3):
public function get_login()
{
try {
$redirect_uri = CustomAuthentication::process(
$_GET['token'],
$_GET['state'],
$_GET['redirect_uri']
);
return Redirect::to($redirect_uri);
} catch (\Exception $e) {
return Response::json(array(
'ok' => false,
'error' => $e->getMessage(),
'code' => $e->getCode()
), 401);
}
}
I found two issues on github that seem relevant:
https://github.com/driftyco/ionic-cloud/issues/53
https://github.com/driftyco/ionic-cloud-angular/issues/22
Apparently there is no way to get this to work at the moment, when the inAppBrowser is hidden. Or is there another option?
In case there's no way to achieve this for now, what would be an alternative, in order to provide the users with a nice login flow, that shoes them a meaningful error message for unsuccessful login attempts?
Should I try to implement this with a visible inAppBrowser? If so, where can I find docs or an example?
Unfortunately the official docs don't tell much (http://docs.ionic.io/services/auth/custom-auth.html#login) and the tutorials I found are outdated.
I had the same issue!!
In your server, you have to redirect when there is an authentication error instead of rendering a JSON.
Something like this:
public function get_login()
{
try {
$redirect_uri = CustomAuthentication::process(
$_GET['token'],
$_GET['state'],
$_GET['redirect_uri']
);
return Redirect::to($redirect_uri);
} catch (\Exception $e) {
$redirect_uri = $_GET['redirect_uri'] . '&' . http_build_query([
'error' => $e->getMessage(),
'state' => 401,
'code' => $e->getCode(),
]);
return Redirect::to($redirect_uri);
}
}
(Sorry if there is an error in the code, I don't know Lavarel ;))
This code is based on https://github.com/ionic-team/ionic-cloud/issues/53#issuecomment-296369084
In the Ruby on Rails world:
error_params = { error: error, state: 401 }
url = "#{params[:redirect_uri]}&#{error_params.to_query}"
redirect_to url
Immediately after I made this change on my server, the ionic application started to work.
anyErrors : any;
in the controller.ts file
this.auth.login('basic', details).then(() => {
this.isUserLoggedIn = true; // <------ Debug here (1)
this.currentUserData = this.user;
console.log(this.currentUserData);
return this.currentUserData;
}, (err: IDetailedError) => {
this.anyErrors= err; // map the error here
});
in the html file
<div >
<ion-row >
<ion-item >
<ion-label text-wrap color=red color="primary" >
{{anyErrors}}
</ion-label>
</ion-item>
</ion-row>
</div>
So any error in ionic .ts will flow the the html page I use this for the login page. i.e below the login submit button, i have the above div code. if there is no error the msg will not display, if there is an error msg it will display.

Ionic2: Property 'present' does not exist on type 'NavController'

I am using Ionic 2 rc4. I am following the advise here and am trying to do the following:
import { NavController } from 'ionic-angular';
...
this.nav.present(this.loading).then(() => {
However, to me it looks like the NavController does not have a present function, because I get:
[ts] Property 'present' does not exist on type 'NavController'.
any
Am I correct, or am I doing something wrong? How do they get to access this "phantom" function?
Any advise appreciated.
UPDATE
Here is my code that results in the following error (on this.loading.present().then(() => {):
"Cannot read property 'nativeElement' of null"
It presents loading the first time. but after the alert is presented if submit() is run again, it gets this error.
submit() {
this.loading.present().then(() => {
let alert = this.alertCtrl.create({
title: 'Verify Email',
subTitle: 'Please verify your email address before you log in.',
message: 'Check your Spam folder if you cannot find the email.',
buttons: [
{
text: 'Resend',
handler: data => {
firebaseUser.sendEmailVerification().then((data) => {
this.doAlert('Verify Email', 'Verification Email Sent.').then((data) => {
//navCtrl.setRoot(navCtrl.getActive());
});
});
}
},
{
text: 'Okay',
handler: data => {
//navCtrl.setRoot(navCtrl.getActive());
}
}
]
});
alert.present();
this.loading.dismiss();
});
}
Looking at this changelog for Beta 11
They have removed present function from Navcontroller.
You need to refactor your code and use some other function based on your requirement.
this.loading.present()
For the error, check the Loading controller docs.
Note that after the component is dismissed, it will not be usable
anymore and another one must be created. This can be avoided by
wrapping the creation and presentation of the component in a reusable
function
Just do :
this.loading = this.loadingCtrl.create({
//loading properties
});
inside submit() before this.loading.present()

Ionic facebook login for native

I have implemented the facebook login for my ionic application, which works perfectly when run on web. When i build the application, create an apk of the same, and try to run on my mobile device, nothing happens.
The login is:
openFB.login(
function (response) {
if (response.status === 'connected') {
console.log('Facebook login succeeded, got access token: ', response);
openFB.api({
path: '/me',
success: function (data) {
console.log("My Data", data);
userData.name = data.name;
userData.picture = 'http://graph.facebook.com/' + data.id + '/picture?type=small';
localStorageService.set('user', userData);
$timeout(function() {
$state.go('app.home');
}, 0);
},
error: function(error) {
console.log("Error here:", error);
}
});
} else {
console.log('Facebook login failed: ' + response);
}
}, { scope: 'email, public_profile' });
Have used openFB for the login. After clicking, following popup comes up.
After clicking the okay, nothing gets logged. No console message.
Can some one help me for finding out this issue, where i am not able to do the facebook login, when run on actual device.
You need to whitelist the redirect url. You can set it in
Products > Facebook Login > Settings > Client OAuth Settings
Take a look into this question.
please set redirect URI in
Products > Facebook Login > Settings > Client OAuth Settings
http://localhost/callback
please follow the below procedure to register your app in facebook developer site
https://ccoenraets.github.io/ionic-tutorial/ionic-facebook-integration.html
and use the below code to complete the procedure of facebook login
$cordovaOauth.facebook("appId", ["email", "public_profile"]).then(function(result) {
//alert(JSON.stringify(result));
//$localStorage.accessToken = result.access_token;
$http.get("https://graph.facebook.com/v2.2/me", {
params: {
access_token: result.access_token,
fields: "id,name,gender,location,email,picture,relationship_status",
format: "json"
}
}).then(function(result) {
// alert(JSON.stringify(result));
$scope.loginflowusingsociallogin(result.data.email);
}, function(error) {
alert("There was a problem getting your profile. Check the logs for details.");
alert(JSON.stringify(error));
});
});
i used Oauth 2.0 authentication for ionic.
I used this code and worked fine for me

Update / Delete a tab from a facebook page using the Graph API returns "(#210) Subject must be a page."

I am trying to delete an application tab from a facebook page.
According to the documentation, I should issue a DELETE request to "https://graph.facebook.com/PAGE_ID/tabs/TAB_ID" with a PAGE access token, but when I do so I get the error "(#210) Subject must be a page."
The same happens when trying to update a tab.
I have requested the user for "manage_pages" permission and I have the correct access_token (Adding a tab works perfectly).
the exact request is: https://graph.facebook.com/212757048770606/tabs/app_289329597785433 (with an access token)
Does anyone know what am I doing wrong?? or is there an open bug report?
Thanks alot
I don't have a solution for you, but I do know that I had some problems with removing a tab that boiled down to the fact that the tab's ID (returned from a call to get /PAGE_ID/tabs) already includes the page ID and "tabs" path.
Initially I was building my URL by taking the tab ID and sticking it on the end of /PAGE_ID/tabs/, but that didn't work because the URL ended up being something like /12345/tabs/12345/tabs/app_4567. Once I realized that the tab ID was sort of "compound" already, I got the Remove to work.
Add the page access token to the call of Facebook API
var PageAccessToken = 123456789123456789123456789123456789;
FB.api(
"/{page_id}/tabs",
"POST",
{
"object": {
"app_id": "{page_id}"
}
},{
"access_token": PageAccessToken
},
function (response) {
if (response && !response.error) {
console.log(response);
} else {
console.log(response.error);
}
}
);
function DeleteTabPage(){
var pid = page_id;
var at = access_tocken;
debugger;
FB.api(pid + '/tabs/app_{your app id}', 'DELETE', { app_id: your app id, access_token: at }, function (response) {
debugger;
if (!response || response.error) {
debugger;`enter code here`
alert('Facebook add app error ' + response.error);
} else {
console.log(response);
debugger;
// alert('App has been added');
}
}); /* end of page/tabs*/
}