FB Graph api not working in build apk - android

I am integrating FB Graph API in my project using following code :
private void integrateFacebook(){
fbLoginButton =(LoginButton)findViewById(R.id.fb_login_button);
callbackManager = CallbackManager.Factory.create();
mLoginManager.getInstance().logInWithReadPermissions(this, Arrays.asList("public_profile"));
fbLoginButton.registerCallback(callbackManager, new FacebookCallback<LoginResult>() {
#Override
public void onSuccess(LoginResult loginResult) {
Log.d("Facebook", "Facebook Login Successful!");
token = loginResult.getAccessToken().toString();
Log.d("Facebook", "User ID : " + loginResult.getAccessToken().getUserId());
GraphRequest request = GraphRequest.newMeRequest(
accessToken,
new GraphRequest.GraphJSONObjectCallback() {
#Override
public void onCompleted(JSONObject object, GraphResponse response) {
// Insert your code here
try {
String name = "";
String id =object.getString("id");
String img_url ="https://graph.facebook.com/"+id+"/picture?type=large";
String email= "";
if(object.has("id")){
name = object.getString("name");
}
if(object.has("email")){
email=object.getString("email");
}
if(object.has("email")){
email=object.getString("email");
}
UserActivation.getsharedInstance(getApplicationContext()).setUserName(name);
UserActivation.getsharedInstance(getApplicationContext()).setUserName(email);
SharedPref.getSharedPref().setValue(getApplicationContext(),"img_url",img_url);
SharedPref.getSharedPref().setValue(getApplicationContext(),"user_email",email);
submitData(name,email,null,null,"1","facebook",img_url,id);
} catch (JSONException e) {
e.printStackTrace();
Log.d(TAG,e.toString());
}catch(Exception e){
Log.d(TAG,e.toString());
}
}
});
Bundle parameters = new Bundle();
parameters.putString("fields", "id, name, photos, picture{url}, email");
// parameters.putString("access_token", token);
request.setParameters(parameters);
request.executeAsync();
}
Now It is working in debug mode but when i try to run through build.apk it gives following error in log :
Request without access token missing application ID or client token.
How to solve this.

In your debug mode you get somehow the Facebook app-related keys and after building the project, the build no longer reaches that. So you need to review your ini files, database connections and other stuff to know why are Facebook credentials missing after the build. Look at how are the credentials used and find out where they come from. When you know the answer to that, you should be able to solve the problem by making sure that the build app reaches the juices.

The android key hash that you generated and entered in your app in the facebook developer panel must have been generated using debug.keystore. SO to make it work for release build you have to generate a release key hash.
Checkout the "Setting a release key hash" section of this Official Documentation

Related

How to get Facebook account's gender and age range in Graph 3.0 API android

Since Facebook becomes more secure in giving user's data things has drastically changed. I am able to get gender and age range in my admin account using Graph 2.12 before using Bundles and Graph Request.
//Log in Facebook
private void signInFacebook() {
//Request a read permission of user's info from Facebook
//Data provided by Facebook will be used for Firebase FireStore
LoginManager.getInstance().logInWithReadPermissions(LogIn.this, Arrays.asList("email", "public_profile"));
LoginManager.getInstance().registerCallback(mCallbackManager, new FacebookCallback<LoginResult>() {
#Override
public void onSuccess(final LoginResult loginResult) {
mStateOfSuccess = false;
//Dismiss any snackbar first before showing a new one
mSnackBar.dismiss();
mSnackBar.show();
Log.d(TAG, "facebook:onSuccess:" + loginResult);
//Bundle is use for passing data as K/V pair like a Map
Bundle bundle=new Bundle();
//Fields is the key of bundle with values that matched the proper Permissions Reference provided by Facebook
bundle.putString("fields","id, email, first_name, last_name, gender, age_range");
//Graph API to access the data of user's facebook account
GraphRequest request = GraphRequest.newMeRequest(
loginResult.getAccessToken(),
new GraphRequest.GraphJSONObjectCallback() {
#Override
public void onCompleted(JSONObject object, GraphResponse response) {
Log.v("Login Success", response.toString());
//For safety measure enclose the request with try and catch
try {
//The get() or getString() key should be included in Bundle otherwise it won't work properly
//If not then error dialog will be called
//First re-initialize jSON object to a new Contructor with parameter that is equal to a jSON format age range
JSONObject ageRange = new JSONObject(object.getString("age_range"));
//Log in using Facebook with Firebase
loginToFirebaseUsingFacebook(loginResult.getAccessToken()
,object.getString("first_name")
,object.getString("last_name")
//Then get again get a string from object itself for the minimum age range
//The idea is that we need to get minimum age only written im string format
//not the whole age range data that is written in jSOM format
,ageRange.getString("min")
,object.getString("gender")
,object.getString("email")
);
}
//If no data has been retrieve throw some error
catch (JSONException e) {
ErrorDialog(e.getMessage(),"facebookAuth");
}
}
});
//Set the bundle's data as Graph's object data
request.setParameters(bundle);
//Execute this Graph request asynchronously
request.executeAsync();
}
#Override
public void onCancel() {
Log.d(TAG, "facebook:onCancel");
ErrorDialog("Request has canceled.","facebookAuth");
}
#Override
public void onError(FacebookException error) {
Log.d(TAG, "facebook:onError", error);
ErrorDialog(String.valueOf(error),"facebookAuth");
}
});
}
But now everything has change and even accessing my own account (admin) does not providing the data I needed. According to their docs enter image description here
I figured it out how to do it in Graph 3.0 all you need to do is to include this user_age_range and user_gender to permission and it will work now as intended when using admin account to log in if app is not yet verified by Facebook.
//Log in Facebook
private void signInFacebook() {
//Request a read permission of user's info from Facebook
//Data provided by Facebook will be used for Firebase FireStore
//For more updates about Read Permissions - User Attributes: ''https://developers.facebook.com/docs/facebook-login/permissions/''
LoginManager.getInstance().logInWithReadPermissions(LogIn.this, Arrays.asList("email","public_profile","user_gender","user_age_range"));
LoginManager.getInstance().registerCallback(mCallbackManager, new FacebookCallback<LoginResult>() {
#Override
public void onSuccess(final LoginResult loginResult) {
mStateOfSuccess = false;
//Dismiss any snackbar first before showing a new one
mSnackBar.dismiss();
mSnackBar.show();
Log.d(TAG, "facebook:onSuccess:" + loginResult);
//Bundle is use for passing data as K/V pair like a Map
Bundle bundle=new Bundle();
//Fields is the key of bundle with values that matched the proper Permissions Reference provided by Facebook
bundle.putString("fields","id,email,first_name,last_name,gender,age_range");
//Graph API to access the data of user's facebook account
GraphRequest request = GraphRequest.newMeRequest(
loginResult.getAccessToken(),
new GraphRequest.GraphJSONObjectCallback() {
#Override
public void onCompleted(JSONObject object, GraphResponse response) {
Log.v("Login Success", response.toString());
//For safety measure enclose the request with a try and catch
try {
//The get() or getString() key should be included in Bundle otherwise it won't work properly
//If not then error dialog will be called
//First re-initialize jSON object to a new Contructor with parameter that is equal to a jSON format age range
JSONObject ageRange = new JSONObject(object.getString(getResources().getString(R.string.age_range)));
//Log in using Facebook with Firebase
loginToFirebaseUsingFacebook(loginResult.getAccessToken()
,object.getString(getResources().getString(R.string.fname))
,object.getString(getResources().getString(R.string.lname))
//Then get again get a string from object itself for the minimum age range
//The idea is that we need to get minimum age only written im string format
//not the whole age range data that is written in jSON format
,ageRange.getString(getResources().getString(R.string.minimum))
,object.getString(getResources().getString(R.string.gender).toLowerCase())
,object.getString(getResources().getString(R.string.mail))
);
}
//If no data has been retrieve throw some error
catch (JSONException e) {
//Log in using Facebook with Firebase
try {
loginToFirebaseUsingFacebook(loginResult.getAccessToken()
,object.getString(getResources().getString(R.string.fname))
,object.getString(getResources().getString(R.string.lname))
//Exception occurs if age and gender has no value
,null
,null
,object.getString(getResources().getString(R.string.mail))
);
} catch (JSONException e1) {
ErrorDialog(e.getMessage(),"facebookAuth");
}
}
}
});
//Set the bundle's data as Graph's object data
request.setParameters(bundle);
//Execute this Graph request asynchronously
request.executeAsync();
}
#Override
public void onCancel() {
Log.d(TAG, "facebook:onCancel");
ErrorDialog("Request has canceled.","facebookAuth");
}
#Override
public void onError(FacebookException error) {
Log.d(TAG, "facebook:onError", error);
ErrorDialog(String.valueOf(error),"facebookAuth");
}
});
}

attempting to get the number of friends from facebook api - android

I am attempting to the number of friends from facebook authentication api in an android application needed to call facebook permission api. Below is a snippet I am using
fbLoginButton.setReadPermissions(Arrays.asList("public_profile, email, user_birthday, user_friends"));
the app fails with a json exception at this line
PUBLICPROFILE = object.getString("public_profile"); //error here
EDITTED - Here is a snippet of my attempt:
Name = object.getString("name");
Email = object.getString("email");
DOB = object.getString("birthday");
DOB = object.getString("birthday");
PUBLICPROFILE = object.getString("/me/friends");
Log.v("Email = ", " " + Email);
Log.v("PUBLIC PROFILE = ", " " + PUBLICPROFILE);
Please does anyone know how I can the number of friends from facebook on android login authentication
As per the facebook developer api /{user-id}/friends
1.the User's friends who have installed the app
2.the User's total number of friends (including those who have not installed the app making the query)
After getting facebook token you can use this implementation
GraphRequest request = GraphRequest.newGraphPathRequest(
accessToken,
"/{user-id}/friends",
new GraphRequest.Callback() {
#Override
public void onCompleted(GraphResponse response) {
// Insert your code here
}
});
request.executeAsync();
https://developers.facebook.com/docs/graph-api/reference/user/friends/

Microsoft Azure Mobile authentication with Google provider SDK in Android

I am currently testing Microsoft Azure and the App Service/Mobile Apps feature using a native Android app and C# on the back end.
I started with the Getting Started application (ToDo) as the base app and now I am trying to enable Authentication using the https://azure.microsoft.com/en-us/documentation/articles/app-service-authentication-overview/ page and Google as the provider.
So far I have
created a Google project with a OAuth Web client
the authorized redirect uri set there is: https://.azurewebsites.net/.auth/login/google/callback
in the Azure portal and the App Service instance I have enabled Authorization/Authentication
the "Action to take when request is not authenticated" option is set to "Allow Request"
For the Google Provider I have set the Client Id and Client Secret
In the Android app I am using the GoogleApiClient class to let the user select a Google Account. Also I get the ID token and the Server Auth Code
GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
.requestEmail()
.requestIdToken(getString(R.string.server_client_id))
.requestServerAuthCode(getString(R.string.server_client_id))
.build();
mScopes = gso.getScopeArray();
mGoogleApiClient = new GoogleApiClient.Builder(this)
.enableAutoManage(this, this)
.addApi(Auth.GOOGLE_SIGN_IN_API, gso)
.build();
Once the user picks up an account I retrieve the token and code and then I ask for an access token using the GoogleAuthUtil class. After I get the access_token I try to exchange it with an App Service token (authenticate2 method)
private void handleSignInResult(GoogleSignInResult result) {
Log.d("", "handleSignInResult: " + result.isSuccess());
if(result.isSuccess()) {
final GoogleSignInAccount account = result.getSignInAccount();
final String idToken = account.getIdToken();
String serverAuthCode = account.getServerAuthCode();
mSignInButton.setVisibility(View.GONE);
mGoogleUserText.setText(account.getDisplayName());
mGoogleUserText.setVisibility(View.VISIBLE);
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
prefs.edit().putString("idToken", idToken).commit();
prefs.edit().putString("serverAuthCode", serverAuthCode).commit();
new AsyncTask<Void, Void, String>() {
#Override
protected String doInBackground(Void... params) {
try {
StringBuilder scopesBuilder = new StringBuilder("oauth2:");
for(Scope scope : mScopes) {
scopesBuilder//.append("https://www.googleapis.com/auth/")
.append(scope.toString())
.append(" ");
}
String token = GoogleAuthUtil.getToken(ToDoActivity.this,
account.getEmail(), scopesBuilder.toString());
return token;
} catch (IOException | GoogleAuthException e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(String result) {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(ToDoActivity.this);
prefs.edit().putString("accessToken", result).apply();
authenticate2();
}
}.execute();
} else {
mSignInButton.setVisibility(View.VISIBLE);
mGoogleUserText.setVisibility(View.GONE);
}
}
private void authenticate2() {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
String idToken = prefs.getString("idToken", null);
String serverAuthCode = prefs.getString("serverAuthCode", null);
String accessToken = prefs.getString("accessToken", null);
JsonObject json = new JsonObject();
json.addProperty("access_token", accessToken);
json.addProperty("id_token", idToken);
json.addProperty("authorization_code", serverAuthCode);
ListenableFuture<MobileServiceUser> loginFuture =
mClient.login(MobileServiceAuthenticationProvider.Google, json);
Futures.addCallback(loginFuture, new FutureCallback<MobileServiceUser>() {
#Override
public void onSuccess(MobileServiceUser result) {
createTable();
}
#Override
public void onFailure(Throwable t) {
Log.e(TAG, t.getMessage(), t);
}
});
}
So I am using the MobileServiceClient.login() method to send back to the server the access_token of the user in order to get back an Azure session.
Nevertheless, this call fails and I get back a MobileServiceException:
com.microsoft.windowsazure.mobileservices.MobileServiceException: You do not have permission to view this directory or page.
Any ideas what am I missing here?
Thanks
Well this is more than embarassing :-)
I first tried to "manually" verify the id_token using the Google tokeninfo endpoint:
https://www.googleapis.com/oauth2/v3/tokeninfo?id_token=
but I was getting a generic error that didn't give a lot of info.
Then I used the Google API Java client library and created a small test to verify my token (more info here: https://developers.google.com/identity/sign-in/android/backend-auth)
That test was failing as well and I realized that the reason for that was the expiring time of my token which was smaller than the current time. And this was happening because my emulator time was not correct!
When I set the "correct" timezone everything worked as expected.
Sorry for the post guys. You can use the code here as a template and don't forget to check your emulator time :-)

Facebook Graph Api Android sharing image on a page

I want to share an image on a Facebook page of mine. But I couldn't figure out how to do this step by step. And couldn't find step by step guide for this.
This is my code to share an image on a page
Bundle params = new Bundle();
String nameText = name.getText().toString();
String tags = engine.implodeTags(tagsList);
String textText = text.getText().toString();
params.putString("caption", nameText + "\n\n" + textText + "\n\n" + tags);
params.putString("url", imagesList.get(mainImageSelected).getImageUrl());
params.putString("access_token", "{access token here}");
new GraphRequest(
AccessToken.getCurrentAccessToken(),
"/{page_id here}/photos",
params,
HttpMethod.POST,
new GraphRequest.Callback() {
public void onCompleted(GraphResponse response) {
if(response.getJSONObject()!=null) {
Log.d("qwe", response.getJSONObject().toString());
activity.runOnUiThread(new Runnable() {
#Override
public void run() {
Toast.makeText(activity, "Shared on facebook", Toast.LENGTH_LONG).show();
progressBar.setVisibility(View.GONE);
}
});
}
else{
activity.runOnUiThread(new Runnable() {
#Override
public void run() {
Toast.makeText(activity, "Error", Toast.LENGTH_LONG).show();
progressBar.setVisibility(View.GONE);
}
});
}
}
}
).executeAsync();
It works if I put access token by hand. I am getting access token here
https://developers.facebook.com/tools/explorer .
But after some time this access token is not working any more. So I need to get new access token.
How to get PAGE access token from android itself? Via user login button of facebook sdk?
https://developers.facebook.com/docs/facebook-login/access-tokens
Please help.
Easily if you use facebook SDK to do that. read at here https://developers.facebook.com/docs/sharing/android
You need to get Permanent access token to share images on your Page. To get that you need to follow steps written here.
facebook: permanent Page Access Token?

Create new ParseUser using Google+ AccessToken returns InvalidSession?

I'm trying to create a new ParseUser using a Google+ SignIn. While I'm able to retrieve the access token successfully from Google, I get a ParseException(InvalidSession).
I'll post a few snippets that are relevant.
This is how im getting the AccessToken from Google
final String SCOPES = "https://www.googleapis.com/auth/plus.login ";
token = GoogleAuthUtil.getToken(
MainActivity.this,
Plus.AccountApi.getAccountName(mGoogleApiClient),
"oauth2:" + SCOPES);
Making ParseUser
ParseUser.becomeInBackground(token, new LogInCallback()
{
public void done(ParseUser user, ParseException e)
{
Log.i(TAG, "makeParseUser"+"2");
if (user != null)
{
// The current user is now set to user.
/*
user.put("name", s1);
user.put("email",s6);
user.saveInBackground();
*/
}else
{
// The token could not be validated.
Log.i(TAG, "makeParseUser"+e.getLocalizedMessage());
}
}
});
A similar question has been asked here but there doesn't seem to be a proper solution to it.
Currently Parse doesn't support G+ login. Practically it can be done by using Parse cloud code.
ParseUser.becomeInBackground(); expects Parse User token, but not G+ one.

Categories

Resources