I'm trying to get the requested information from Facebook Provider of Firebase AuthUI.
I didn't find any method to get this data. When I debug that step, I can see the requested information in the attribute "zzdd" as JSON like.
How can I get this data?
Request birthday and gender information from user:
new AuthUI.IdpConfig.FacebookBuilder()
.setPermissions( Arrays.asList( "user_birthday", "user_gender" ) )
.build() );
Fetch data from provider
mUser = FirebaseAuth.getInstance().getCurrentUser();
for( UserInfo user : mUser.getProviderData() ) { }
Debbuger - user - zzdd attribute
{"birthday":"08/05/1995","updated_time":"2018-05-04T21:28:53+0000","gender":"male",...}
Firebase AuthUI Version: 3.3.1
I found the solution.
To get additional information by Firebase Auth you must get by SDK providers, like Facebook as code below:
Get data from Facebook SDK on Login Success with Firebase AuthUI:
GraphRequest request = GraphRequest.newMeRequest(
AccessToken.getCurrentAccessToken(),
new GraphRequest.GraphJSONObjectCallback() {
#Override
public void onCompleted( JSONObject jsonObject, GraphResponse response ) {
// Application code
try {
String birthday = jsonObject.getString( "birthday" );
String gender = jsonObject.getString( "gender" );
} catch( JSONException e ) {
e.printStackTrace();
}
}
} );
Bundle parameters = new Bundle();
parameters.putString( "fields", "birthday,gender" );
request.setParameters( parameters );
request.executeAsync();
Related
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");
}
});
}
I have an Android app that allows users to login with Facebook with their Login button. I've set the permission as follow for the loginButton :
loginButton.setReadPermissions(
"public_profile","user_birthday","user_location");
The login works fine but what i want to do is basically get some additional info about their birthdate and actual location in order to create a new "User" object and write it into my database in this way :
Bundle parameters = new Bundle();
parameters.putString("fields", "id,first_name,last_name,gender, birthday,link,location");
final User newUser= new User();
GraphRequest request = GraphRequest.newMeRequest(
loginResult.getAccessToken(),
new GraphRequest.GraphJSONObjectCallback() {
#Override
public void onCompleted(JSONObject object, GraphResponse response) {
Log.i("***LoginResponse :",response.toString());
try {
String userGender = response.getJSONObject().getString("gender");
String firstName = response.getJSONObject().getString("first_name");
String lastName = response.getJSONObject().getString("last_name");
String facebookProfileLink = response.getJSONObject().getString("link");
String userBirthdate = response.getJSONObject().getString("birthday");
String userCity = response.getJSONObject().getJSONObject("location").getString("name");
Profile profile = Profile.getCurrentProfile();
String id = profile.getId();
String link = profile.getLinkUri().toString();
Uri profilePicture = profile.getProfilePictureUri(200,200);
Log.i("Link",link);
newUser.setUserAge(userBirthdate);
Log.i("****Login" + "UserBirthday", userBirthdate);
newUser.setUserEmail("default#facebook.com");
newUser.setUserGender(genderFixer(userGender));
newUser.setUserCity(userCity);
Log.i("****Login" + "UserCity", userCity);
newUser.setFacebookProfile(facebookProfileLink);
newUser.setUserName(firstName);
newUser.setUserSurname(lastName);
newUser.setProfileImage(profilePicture.toString());
String userId = mAuth.getCurrentUser().getUid();
mDatabaseReference.child(userId).setValue(newUser);
if (Profile.getCurrentProfile()!=null)
{
Log.i("Login", "ProfilePic" + Profile.getCurrentProfile().getProfilePictureUri(200, 200));
}
Log.i("****Login"+ "FirstName", firstName);
Log.i("****Login" + "LastName", lastName);
Log.i("****Login" + "Gender", userGender);
}catch (JSONException e) {
e.printStackTrace();
}
}
}
);
request.setParameters(parameters);
request.executeAsync();
}
I can read all the data but not "birthday" and "location" -> "name".
NOTE : i'm perfectly aware that those fields can be empty and i know how to handle it but i'm testing with an account that actually has those fields on the Facebook profile. This is the response i'm getting :
I/***LoginResponseĀ :: {Response: responseCode: 200,
graphObject: {
"id":"116293545526048",
"first_name":"Davide",
"last_name":"Harlee",
"gender":"male",
"link":"https:\/\/www.facebook.com\/app_scoped_user_id\/116293545526048\/"}, error: null}
This only happens on 2 test account i made while logging with my "real" facebook account i get all the information i need without problems getting location and birthday just fine
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
Code i used for fetching the list after doing some search is below
GraphRequestBatch batch = new GraphRequestBatch(
GraphRequest.newMyFriendsRequest(
accessToken,
new GraphRequest.GraphJSONArrayCallback() {
#Override
public void onCompleted(
JSONArray jsonArray,
GraphResponse response) {
// Application code for users friends
System.out.println("getFriendsData onCompleted : jsonArray " + jsonArray);
System.out.println("getFriendsData onCompleted : response " + response);
try {
JSONObject jsonObject = response.getJSONObject();
System.out.println("getFriendsData onCompleted : jsonObject " + jsonObject);
JSONObject summary = jsonObject.getJSONObject("summary");
System.out.println("getFriendsData onCompleted : summary total_count - " + summary.getString("total_count"));
} catch (Exception e) {
e.printStackTrace();
}
}
})
);
batch.addCallback(new GraphRequestBatch.Callback() {
#Override
public void onBatchCompleted(GraphRequestBatch graphRequests) {
// Application code for when the batch finishes
}
});
batch.executeAsync();
Bundle parameters = new Bundle();
parameters.putString("fields", "id,name,link,picture");
and the permission i get is
accessToken : {AccessToken token:ACCESS_TOKEN_REMOVED permissions:[user_friends, basic_info]}
getRecentlyGrantedPermissions : [user_friends, basic_info]
getRecentlyDeniedPermissions : []
and the output of the graph function is -
response {Response: responseCode: 200, graphObject: {"summary":{"total_count":3},"data":[]}, error: null}
so can anyone please guide me to fetch the friend list of user .
Thanx in advance .
The output is correct, none of your friends authorized your App yet. Since v2.0 of the Graph API you can only get the friends who authorized your App, for privacy reasons: https://developers.facebook.com/docs/graph-api/reference/v2.3/user/friends
More information can be found in this thread: Get ALL User Friends Using Facebook Graph API - Android
I am using the Facebook Android SDK. Is there an easy way to get a user's friends who have downloaded the app? For example, the app Draw Something implements this. I can't seem to find any information on this subject
I would guess that if it was possible, some extra information would be needed in the httppost to access this information.
* Note: since 3.14 version, me/friends will only return friends that also use the app, so below implementation is deprecated. See the new "Invitable Friends" or "Taggable Friends" APIs for alternatives.
Using the new Facebook SDK for Android (3.0) is very easy to get your user's friend list.
Following is the code:
private void requestFacebookFriends(Session session) {
Request.executeMyFriendsRequestAsync(session,
new Request.GraphUserListCallback() {
#Override
public void onCompleted(List<GraphUser> users,
Response response) {
// TODO: your code for friends here!
}
});
}
Nevertheless, in order to get the user's friends who are using your Facebook app is a little bit complicated (due to Facebook API documentation). But yes, it is possible.
First of all, create your request:
private Request createRequest(Session session) {
Request request = Request.newGraphPathRequest(session, "me/friends", null);
Set<String> fields = new HashSet<String>();
String[] requiredFields = new String[] { "id", "name", "picture",
"installed" };
fields.addAll(Arrays.asList(requiredFields));
Bundle parameters = request.getParameters();
parameters.putString("fields", TextUtils.join(",", fields));
request.setParameters(parameters);
return request;
}
Note that you need to insert the field "installed" in your request. I'm requesting the user picture path with the same request. Check your possibilities here.
Next, you can use above code to create your request and then get your friends:
private void requestMyAppFacebookFriends(Session session) {
Request friendsRequest = createRequest(session);
friendsRequest.setCallback(new Request.Callback() {
#Override
public void onCompleted(Response response) {
List<GraphUser> friends = getResults(response);
// TODO: your code here
}
});
friendsRequest.executeAsync();
}
Note that using this generic request, you don't receive a GraphUser list as response. You'll need following code to get the response as GraphUser list:
private List<GraphUser> getResults(Response response) {
GraphMultiResult multiResult = response
.getGraphObjectAs(GraphMultiResult.class);
GraphObjectList<GraphObject> data = multiResult.getData();
return data.castToListOf(GraphUser.class);
}
Now you can use your user's friend list, with the information if each of your friends use your Facebook app:
GraphUser user = friends.get(0);
boolean installed = false;
if(user.getProperty("installed") != null)
installed = (Boolean) user.getProperty("installed");
I implemented it in this way
Bundle params = new Bundle();
params.putString("fields", "name, picture, location, installed");
And during displaying of the items on the list,in the getView() method i did this
boolean b = jsonObject.getBoolean("installed");
if (b){
Log.d("VIVEK",jsonObject.getString("name"));
}
I hope this post helps you:
How can i get my friends using my facebook App with graph api asp.net
According to the Facebook SDK, the has_added_app field is deprecated and you should use the is_app_user