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
Related
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();
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/
I'm developing an Android app and a RESTful API with Laravel 5 Framework.
I've got a trouble with the login activity: the flow is that the user ask a 8th characters code and the server web sends him a SMS with it. Then user can do the login using this code like a password.
This is the code that asks a code:
private void askCode(String mobile) {
GsonRequest<String> jsObjRequest = new GsonRequest<String>(
Request.Method.GET,
WebAPIRoute.authGetCode + "/" + mobile,
String.class, null,
new Response.Listener<String>() {
#Override
public void onResponse(String code) {
txtResponse.setText("Code asked successfully.");
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError volleyError) {
Toast.makeText(getBaseContext(), volleyError.getMessage(), Toast.LENGTH_SHORT).show();
}
});
this.requestQueue.add(jsObjRequest);
}
And this the method in the RESTful API to generate a code:
public function getCode($mobileNum)
{
//genero un numero casuale da mandare con l'sms
$code = mt_rand(10000000, 99999999);
Session::put('code', $code);
sendCode($mobileNum, $code); //send code by SMS
return response()->json(array("success"=>true));
}
The code generated is stored into Laravel's Session (configurated with file driver).
When the user wants to login, the app call this method:
private void saveUser(final String code, final String mobile, final String name) {
HashMap<String, String> params = new HashMap<String, String>();
params.put("nickname", name);
params.put("mobile", mobile);
params.put("code", code);
GsonRequest<String> jsObjRequest = new GsonRequest<String>(
Request.Method.POST,
WebAPIRoute.authValidateCode,
String.class,
params,
new Response.Listener<String>() {
#Override
public void onResponse(String authtoken) {
final Account account = new Account(accountName, mAccountType);
String authtokenType = mAuthTokenType;
// Creating the account on the device and setting the auth token we got
// (Not setting the auth token will cause another call to the server to authenticate the user)
mAccountManager.addAccountExplicitly(account, code, null);
mAccountManager.setAuthToken(account, authtokenType, authtoken);
Bundle data = new Bundle();
data.putString(AccountManager.KEY_ACCOUNT_NAME, accountName);
data.putString(AccountManager.KEY_ACCOUNT_TYPE, mAccountType);
data.putString(AccountManager.KEY_AUTHTOKEN, authtoken);
data.putString(PARAM_USER_PASS, code);
data.putBoolean(ARG_IS_ADDING_NEW_ACCOUNT, true);
final Intent res = new Intent();
res.putExtras(data);
setAccountAuthenticatorResult(res.getExtras());
Intent i = new Intent(getBaseContext(), MyEventsActivity.class);
startActivity(i);
}
}
,
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError volleyError) {
Log.e(TAG, volleyError.getMessage(), volleyError);
showMessage("Errore nell'autenticazione. Riprova piu` tardi.");
}
});
requestQueue.add(jsObjRequest);
}
The method of API that validate the code is this:
public function validateCode() {
$code = trim(Input::get('code'));
$nickName = trim(Input::get('nickname'));
$phoneNum = trim(Input::get('mobile'));
if (empty($phoneNum))
abort(400, 'mobile parameters not provided.');
if (empty($code))
abort(400, 'code parameters not provided.');
if (empty($nickName))
abort(400, 'nickname parameters not provided.');
$validCode = Session::get('code');
Log::info('code: ' . $code . " validCode: " . $validCode);
if($code == $validCode) {
Session::forget('code');
// Retrieve the user by the attributes, or instantiate a new instance...
$user = User::firstOrCreate(['Mobile' => $phoneNum]);
//aggiorno i campi nickname e password col nuovo codice
$user->Nickname = $nickName;
$user->password = $code;
//save!
$user->save();
//viene usata l'autenticazione di Laravel e gli serve una password
$token = JWTAuth::attempt(['Mobile' => $phoneNum, 'password' => $code]);
return response()->json($token);
} else {
//return response()->json(array('success' => false, 'error' => 'The code isn\'t correct.'));
abort(401, 'The code isn\'t correct.' . $validCode);
}
}
I've tested the RESTful API with Chrome and Firefox and the login works. With the app no. Infact the issue is that Session::get('code'); in validateCode returns always an empty value. I checked the Session file generated with Session::put('code', $code); and is correct. But when Session::get('code') is called, Laravel generates another Session file and seems not use the previous.
I disabled the CSRF Middleware in RESTful API.
What is wrong?
Storing the session on the server side is pointless. API's are suppose to be stateless so the second you finish the first request for the code and store it in a session on the server side, the session will end and the next request will not remember anything you set.
If you wanted to keep the code login and avoid using tokens, then you will have to send a unique code from the android app which identifies the user. Then generate the code on the server side and store it in a table with user_identifier and generated_code and create a model to access it e.g.
AttemptedLogin
user_id | generatedCode
0001 | 87392042
0032 | 83214320
Then on add this to saveUser
params.put("user_id", user_id); // can be the android device ID or even a unique timestamp
Finally on the server side in validateCode replace $validCode line with the following:
$user_id = trim(Input::get('user_id'));
....
$validCode = AttemptedLogin::where('user_id', $user_id)->first();
if($code == $validCode->generatedCode) {
$validCode->delete();
....
I am writing an application that needs to use the user data taken from the client social network VKontakte.
I did authorize VKontakte.
VKSdk.initialize(sdkListener, String.valueOf(idVK), VKAccessToken.tokenFromSharedPreferences(this, sTokenKey));
And got AccessToken.
As now I get the name and email user?
You can request email scope from user, then get email from access token:
String email = VKSdk.getAccessToken().email;
String userId = VKSdk.getAccessToken().userId;
//Get user info
VKApi.users().get().executeWithListener(new VKRequest.VKRequestListener() {
#Override
public void onComplete(VKResponse response) {
VKApiUser user = ((VKList<VKApiUser>)response.parsedModel).get(0);
Log.d("User name", user.first_name + " " + user.last_name);
}
});
But remember, email is only available after first access request.
Old answer:
You can't get an email. This is not available. But you can get user name:
VKApi.users().get().executeWithListener(new VKRequest.VKRequestListener() {
#Override
public void onComplete(VKResponse response) {
VKApiUser user = ((VKList<VKApiUser>)response.parsedModel).get(0);
Log.d("User name", user.first_name + " " + user.last_name);
}
});
For now, you can't get user email.
But you can get other simple info from user profile via class
java.lang.Object
com.vk.sdk.VKObject
com.vk.sdk.api.model.VKApiModel
Here is all available info:
http://vkcom.github.io/vk-android-sdk/com/vk/sdk/api/model/VKUser.html
After login user
I use this code
final VKRequest request = VKApi.users().get(VKParameters.from(VKApiConst.FIELDS, "photo_200, contacts"));
request.executeWithListener(new VKRequest.VKRequestListener() {
#Override
public void onComplete(VKResponse response) {
VKApiUserFull user = ((VKList<VKApiUserFull>)response.parsedModel).get(0);
NavigationHelper.replaceFragment(getActivity().getSupportFragmentManager(), FrHome.newInstance(String.format("%s %s,", user.first_name, user.last_name), user.mobile_phone, user.photo_200), false);
}
});
List fields you can found here
https://vk.com/dev/users.get
I am trying to integrate Facebook API for login functionality in android. I need email Id for respective user. I am getting JSON in response but It has no email Id.How can I achieve to get the email Id.
public void getProfileInformation() {
mAsyncRunner.request("me", new RequestListener() {
#Override
public void onComplete(String response, Object state) {
Log.d("Profile", response);
String json = response;
try {
// Facebook Profile JSON data
JSONObject profile = new JSONObject(json);
// getting name of the user
final String name = profile.getString("name");
// getting email of the user
final String email = profile.getString("email");
runOnUiThread(new Runnable() {
// Dayanand plzz check this log n let me know.
#Override
public void run() {
Toast.makeText(getApplicationContext(), "Name: " + name + "\nEmail: " + email, Toast.LENGTH_LONG).show();
}
});
} catch (JSONException e) {
e.printStackTrace();
}
}
Here is code, Where I am getting null in Toast. It goes to catch method.Please help
You have to ask for the permission : email from the user.
You need to ask for the email permission to the user, otherwise you can't get it.
Once the user grants you the permission, you'll see it when requesting for me.
See http://developers.facebook.com/docs/reference/login/email-permissions/
When you first time login at that time you are passing one permission array. so, you have to pass this array for email permission..
private String[] permissions = {"publish_stream","email","user_about_me","user_status"};