i'm tryng to integrate facebook login in my android application. For now i get a new row in Parse Backend about the logged user which contains his real name, some weird value(ex:SnvvKEsIv6tX7...) in his userName, and an authData which is Json and contains the following values:
access_token, expiration date, id.
After debugging i got the url of the json response, it only contains two values, the name and the id, however i declared the list like this:
List permissions = Arrays.asList("public_profile", "email");
So for now the graph is only returnin two values, i thought it was due to the permissions but as i sayed i did declared. Here is my code:
public class LoginActivity extends Activity {
private Dialog progressDialog;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
FacebookSdk.sdkInitialize(getApplicationContext());
ParseFacebookUtils.initialize(this);
// Check if there is a currently logged in user
// and it's linked to a Facebook account.
ParseUser currentUser = ParseUser.getCurrentUser();
if ((currentUser != null) && ParseFacebookUtils.isLinked(currentUser)) {
// Go to the user info activity
showUserDetailsActivity();
}
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
ParseFacebookUtils.onActivityResult(requestCode, resultCode, data);
}
public void onLoginClick(View v) {
progressDialog = ProgressDialog.show(LoginActivity.this, "", "Logging in...", true);
List<String> permissions = Arrays.asList("public_profile", "email");
// NOTE: for extended permissions, like "user_about_me", your app must be reviewed by the Facebook team
// (https://developers.facebook.com/docs/facebook-login/permissions/)
ParseFacebookUtils.logInWithReadPermissionsInBackground(this, permissions, new LogInCallback() {
#Override
public void done(ParseUser user, ParseException err) {
progressDialog.dismiss();
if (user == null) {
Log.d("TAG", "Uh oh. The user cancelled the Facebook login.");
} else if (user.isNew()) {
GraphRequest.newMeRequest(AccessToken.getCurrentAccessToken(),
new GraphRequest.GraphJSONObjectCallback() {
#Override
public void onCompleted(JSONObject fbUser,
GraphResponse response) {
/*
* If we were able to successfully retrieve the
* Facebook user's name, let's set it on the
* fullName field.
*/
Log.e("facebook User", fbUser.toString());
final ParseUser parseUser = ParseUser
.getCurrentUser();
if (fbUser != null
&& parseUser != null
&& fbUser.optString("name").length() > 0) {
parseUser.put("name",
fbUser.optString("name"));
parseUser.put("email",
fbUser.optString("email"));
Log.v("isnew, values: ","values : "+fbUser.optString("name")+","+fbUser.optString("email")+","+fbUser.optString("age_range")+","+fbUser.optString("locale"));
parseUser
.saveInBackground(new SaveCallback() {
#Override
public void done(
ParseException e) {
if (e != null) {
Log.v("", (getString(R.string.com_parse_ui_login_warning_facebook_login_user_update_failed)
+ e.toString()));
}
ParseInstallation installation = ParseInstallation
.getCurrentInstallation();
installation
.put(ParseConstants.KEY_USER_ID,
parseUser
.getUsername());
installation
.saveInBackground();
showUserDetailsActivity();
}
});
}
}
}).executeAsync();
} else {
Log.d("TAG", "User not new logged in through Facebook!");
showUserDetailsActivity();
}
}
});
}
private void showUserDetailsActivity() {
Intent intent = new Intent(this, UserDetailsActivity.class);
startActivity(intent);
}
}
public class UserDetailsActivity extends Activity {
private ProfilePictureView userProfilePictureView;
private TextView userNameView;
private TextView userGenderView;
private TextView userEmailView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.userdetails);
userProfilePictureView = (ProfilePictureView) findViewById(R.id.userProfilePicture);
userNameView = (TextView) findViewById(R.id.userName);
userGenderView = (TextView) findViewById(R.id.userGender);
userEmailView = (TextView) findViewById(R.id.userEmail);
//Fetch Facebook user info if it is logged
ParseUser currentUser = ParseUser.getCurrentUser();
if ((currentUser != null) && currentUser.isAuthenticated()) {
makeMeRequest();
}
}
#Override
public void onResume() {
super.onResume();
ParseUser currentUser = ParseUser.getCurrentUser();
if (currentUser != null) {
// Check if the user is currently logged
// and show any cached content
updateViewsWithProfileInfo();
} else {
// If the user is not logged in, go to the
// activity showing the login view.
startLoginActivity();
}
}
private void makeMeRequest() {
GraphRequest request = GraphRequest.newMeRequest(AccessToken.getCurrentAccessToken(),
new GraphRequest.GraphJSONObjectCallback() {
#Override
public void onCompleted(JSONObject jsonObject, GraphResponse graphResponse) {
if (jsonObject != null) {
JSONObject userProfile = new JSONObject();
try {
userProfile.put("facebookId", jsonObject.getLong("id"));
userProfile.put("name", jsonObject.getString("name"));
if (jsonObject.getString("gender") != null)
userProfile.put("gender", jsonObject.getString("gender"));
if (jsonObject.getString("email") != null)
userProfile.put("email", jsonObject.getString("email"));
// Save the user profile info in a user property
ParseUser currentUser = ParseUser.getCurrentUser();
currentUser.put("profile", userProfile);
currentUser.saveInBackground();
// Show the user info
updateViewsWithProfileInfo();
} catch (JSONException e) {
Log.d("TAG",
"Error parsing returned user data. " + e);
}
} else if (graphResponse.getError() != null) {
switch (graphResponse.getError().getCategory()) {
case LOGIN_RECOVERABLE:
Log.d("TAG",
"Authentication error: " + graphResponse.getError());
break;
case TRANSIENT:
Log.d("TAG",
"Transient error. Try again. " + graphResponse.getError());
break;
case OTHER:
Log.d("TAG",
"Some other error: " + graphResponse.getError());
break;
}
}
}
});
request.executeAsync();
}
private void updateViewsWithProfileInfo() {
ParseUser currentUser = ParseUser.getCurrentUser();
if (currentUser.has("profile")) {
JSONObject userProfile = currentUser.getJSONObject("profile");
try {
if (userProfile.has("facebookId")) {
userProfilePictureView.setProfileId(userProfile.getString("facebookId"));
} else {
// Show the default, blank user profile picture
userProfilePictureView.setProfileId(null);
}
if (userProfile.has("name")) {
userNameView.setText(userProfile.getString("name"));
} else {
userNameView.setText("");
}
if (userProfile.has("gender")) {
userGenderView.setText(userProfile.getString("gender"));
} else {
userGenderView.setText("");
}
if (userProfile.has("email")) {
userEmailView.setText(userProfile.getString("email"));
} else {
userEmailView.setText("");
}
} catch (JSONException e) {
Log.d("TAG", "Error parsing saved user data.");
}
}
}
public void onLogoutClick(View v) {
logout();
}
private void logout() {
// Log the user out
ParseUser.logOut();
// Go to the login view
startLoginActivity();
}
private void startLoginActivity() {
Intent intent = new Intent(this, LoginActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
}
}
i'm using Parse 1.9.4 and ParseFacebookUtils 1.9.4.
Related
I am developing an app which has signup and Login using parse server,in which i am able to signup but when i try to login it gives me exception
"Invalid username/password"
This is the code for signUp and LogIn,when the signUpMode is active the user is signedup on pressing the button alternatively when signUpmode is deactive i.e false the button acts as Login and the user can login but here when i try to login its saying "Invalid Username/password"
public void signUp(View view)
{
editTextUser =(EditText) findViewById(R.id.userNameEdit);
editTextPass =(EditText) findViewById(R.id.passWordEdit);
if(editTextUser.getText().toString().matches("") || editTextPass.getText().toString().matches(""))
{
Toast.makeText(this,"Username and Password required",Toast.LENGTH_SHORT).show();
}
else
{
if(SignupModeActive)
{
ParseUser user = new ParseUser();
user.setUsername(editTextUser.getText().toString());
user.setPassword(editTextUser.getText().toString());
user.signUpInBackground(new SignUpCallback() {
#Override
public void done(ParseException e) {
if(e == null)
{
Log.i("saveInBackGround","SignUp Success");
Intent intent = new Intent(MainActivity.this,UserslistActivity.class);
startActivity(intent);
}
else{
Toast.makeText(MainActivity.this,e.getMessage(),Toast.LENGTH_SHORT).show();
}
}
});
}
else
{
ParseUser.logInInBackground(editTextUser.getText().toString(),editTextPass.getText().toString(), new LogInCallback() {
#Override
public void done(ParseUser user, ParseException e) {
if(user != null){
Log.i("LogInBackGround","Login Succesfull");
Intent logInintent = new Intent(MainActivity.this,UserslistActivity.class);
startActivity(logInintent);
}
else
{
Toast.makeText(MainActivity.this,e.getMessage(),Toast.LENGTH_LONG).show();
}
}
});
}
}
}
//Check your Exception
public void signUp(View view)
{
mEditTextUser =(EditText) findViewById(R.id.userNameEdit);
mEditTextPass =(EditText) findViewById(R.id.passWordEdit);
if(mEditTextUser .getText().toString().trim().length()==0 || editTextPass.getText().toString().trim().length()==0.matches(""))
{
Toast.makeText(this,"Username and Password required",Toast.LENGTH_SHORT).show();
}
else
{
//Check SignupMode is true
if(SignupModeActive)
{
ParseUser user = new ParseUser();
user.setUsername(editTextUser.getText().toString());
user.setPassword(editTextUser.getText().toString());
user.signUpInBackground(new SignUpCallback() {
#Override
public void done(ParseException e) {
if(e == null)
{
Log.e("Exception",e.printStackTrace());
Intent intent = new Intent(MainActivity.this,UserslistActivity.class);
startActivity(intent);
}
else{
Toast.makeText(MainActivity.this,e.getMessage(),Toast.LENGTH_SHORT).show();
}
}
});
}
else
{
ParseUser.logInInBackground(editTextUser.getText().toString(),editTextPass.getText().toString(), new LogInCallback() {
#Override
public void done(ParseUser user, ParseException e) {
if(user != null){
Log.i("LogInBackGround","Login Succesfull");
Intent logInintent = new Intent(MainActivity.this,UserslistActivity.class);
startActivity(logInintent);
}
else
{
Toast.makeText(MainActivity.this,e.getMessage(),Toast.LENGTH_LONG).show();
}
}
});
}
}
}
Your codes for login is okay i will say u check whether the details you are feeding is true or not. Maybe their isn't any user with that name or password u feed is wrong .
I am using similar codes and it works fine. my codes are :-
ParseUser.logInInBackground(edtEmail.getText().toString(),
edtPassword.getText().toString(), new LogInCallback() {
#Override
public void done(ParseUser user, ParseException e) {
if (user != null && e == null) {
FancyToast.makeText(Login.this, user.get("username") + " is logged in successfully", FancyToast.LENGTH_LONG, FancyToast.SUCCESS, true).show();
transitionToWelcomePage();
} else {
FancyToast.makeText(Login.this, e.getMessage(), FancyToast.LENGTH_LONG, FancyToast.ERROR, true).show();
}
}
});
I'm trying to login from Facebook and Google API, the Google API works fine, the problem arises with Facebook login, everything is setup on the Facebook developers console and my app is live as well.
The problem is whenever user clicks on the login button (which is a customized ImageButton) the ProgressBar shows up and then it goes away and the app is still on the same activity without user being logged in.
The complete code for that activity is:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_opening);
progressDialog = new ProgressDialog(this);
mAuth = FirebaseAuth.getInstance();
Auth = FirebaseAuth.getInstance();
if (mAuth.getCurrentUser() != null) {
Intent intent = new Intent(this, MainActivity.class);
startActivity(intent);
finish();
}
GoogleSignInOptions gso = new GoogleSignInOptions
.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
.requestIdToken(getString(R.string.default_web_client_id))
.requestEmail()
.build();
mGoogleSignInClient = GoogleSignIn.getClient(this, gso);
Google = (ImageView) findViewById(R.id.googleSignin);
Google.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
SIGN_IN_REQUEST = 1;
signIn();
progressDialog.setMessage("Loading...");
progressDialog.setCancelable(false);
progressDialog.show();
}
});
callbackManager = CallbackManager.Factory.create();
Facebook = (ImageView) findViewById(R.id.facebookSignin);
Facebook.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
SIGN_IN_REQUEST = 2;
progressDialog.show();
progressDialog.setCancelable(false);
progressDialog.setMessage("Loading...");
LoginManager.getInstance().logInWithReadPermissions(opening.this, Arrays.asList("email", "public_profile"));
LoginManager.getInstance().registerCallback(callbackManager, new FacebookCallback<LoginResult>() {
#Override
public void onSuccess(LoginResult loginResult) {
Log.d(TAG2, "facebook:onSuccess:" + loginResult);
handleFacebookAccessToken(loginResult.getAccessToken());
setFbData(loginResult);
progressDialog.dismiss();
}
#Override
public void onCancel() {
Log.d(TAG2, "facebook:onCancel");
Toast.makeText(getApplicationContext(),"facebook:oncancel",Toast.LENGTH_LONG).show();
progressDialog.dismiss();
}
#Override
public void onError(FacebookException error) {
Log.d(TAG2, "facebook:onError", error);
Toast.makeText(getApplicationContext(),"facebook:onError",Toast.LENGTH_LONG).show();
progressDialog.dismiss();
}
});
}
});
Email = (ImageView)findViewById(R.id.emailLogin);
Email.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent(getApplicationContext(), SignIn.class);
startActivity(intent);
finish();
}
});
AlreadyLoggedin = (ImageView)findViewById(R.id.Already);
AlreadyLoggedin.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent(getApplicationContext(), login.class);
startActivity(intent);
finish();
}
});
}
private void signIn(){
Intent signInIntent = mGoogleSignInClient.getSignInIntent();
startActivityForResult(signInIntent, RC_SIGN_IN);
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data){
super.onActivityResult(requestCode, resultCode, data);
if (SIGN_IN_REQUEST == 1) {
if (requestCode == RC_SIGN_IN) {
Task<GoogleSignInAccount> task = GoogleSignIn.getSignedInAccountFromIntent(data);
try {
GoogleSignInAccount account = task.getResult(ApiException.class);
firebaseAuthWithGoogle(account);
} catch (ApiException e) {
Toast.makeText(getApplicationContext(), "Google sign in Failed", Toast.LENGTH_LONG).show();
String s1 = task.getException().getMessage();
Toast.makeText(getApplicationContext(),"" + s1,Toast.LENGTH_LONG).show();
progressDialog.dismiss();
String s = task.getException().getMessage();
Toast.makeText(getApplicationContext(),"ErrorCode: " + s,Toast.LENGTH_LONG).show();
}
}
} else if (SIGN_IN_REQUEST == 2){
callbackManager.onActivityResult(requestCode, resultCode, data);
}
}
private void firebaseAuthWithGoogle(GoogleSignInAccount acct) {
Log.d(TAG, "firebaseAuthWithGoogle:" + acct.getId());
AuthCredential credential = GoogleAuthProvider.getCredential(acct.getIdToken(), null);
mAuth.signInWithCredential(credential)
.addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull Task<AuthResult> task) {
if (task.isSuccessful()) {
// Sign in success, update UI with the signed-in user's information
Log.d(TAG, "signInWithCredential:success");
FirebaseUser user = mAuth.getCurrentUser();
updateUI(user);
} else {
// If sign in fails, display a message to the user.
Log.w(TAG, "signInWithCredential:failure", task.getException());
Snackbar.make(findViewById(R.id.snake), "Authentication Failed.", Snackbar.LENGTH_SHORT).show();
progressDialog.dismiss();
updateUI(null);
}
// ...
}
});
}
#Override
protected void onStart() {
super.onStart();
FirebaseUser currentUser = mAuth.getCurrentUser();
updateUI(currentUser);
}
private void updateUI(FirebaseUser user) {
/*
Intent intent = new Intent(opening.this, MainActivity.class);
startActivity(intent);
finish();
*/
progressDialog.dismiss();
if (SIGN_IN_REQUEST == 1) {
GoogleSignInAccount acct = GoogleSignIn.getLastSignedInAccount(getApplicationContext());
if (acct != null) {
String personName = acct.getDisplayName();
String personGivenName = acct.getGivenName();
String personFamilyName = acct.getFamilyName();
String personEmail = acct.getEmail();
String personId = acct.getId();
Uri personPhoto = acct.getPhotoUrl();
String uid = mAuth.getCurrentUser().getUid();
Intent intent = new Intent(opening.this, userInf.class);
intent.putExtra("UID", uid);
intent.putExtra("Phone", PhoneNumber);
intent.putExtra("Name", personName);
startActivity(intent);
finish();
}
} else if (SIGN_IN_REQUEST == 2) {
if (user != null) {
progressDialog.dismiss();
Intent intent = new Intent(opening.this, userInf.class);
intent.putExtra("Phone", PhoneNumber);
intent.putExtra("Name", Name);
startActivity(intent);
finish();
} else {
Toast.makeText(getApplicationContext(),"updating error",Toast.LENGTH_LONG).show();
}
}
}
private void setFbData(final LoginResult loginResult){
GraphRequest request = GraphRequest.newMeRequest(loginResult.getAccessToken(),
new GraphRequest.GraphJSONObjectCallback() {
#Override
public void onCompleted(JSONObject object, GraphResponse response) {
try {
String first_name = response.getJSONObject().getString("first_name");
String last_name = response.getJSONObject().getString("last_name");
Name = String.valueOf(first_name + " " + last_name);
} catch (JSONException e){
e.printStackTrace();
}
}
});
}
private void handleFacebookAccessToken(AccessToken token) {
Log.d(TAG, "handleFacebookAccessToken:" + token);
Toast.makeText(getApplicationContext(),"HandelingRequest",Toast.LENGTH_LONG).show();
AuthCredential credential = FacebookAuthProvider.getCredential(token.getToken());
Auth.signInWithCredential(credential)
.addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull Task<AuthResult> task) {
if (task.isSuccessful()) {
Log.d(TAG, "signInWithCredential:success");
FirebaseUser user = mAuth.getCurrentUser();
progressDialog.dismiss();
updateUI(user);
} else {
Log.w(TAG, "signInWithCredential:failure", task.getException());
Toast.makeText(opening.this, "Authentication failed.",
Toast.LENGTH_SHORT).show();
progressDialog.dismiss();
updateUI(null);
}
}
});
}}
The log out is something like this:
D/FACELOG: facebook:onSuccess:com.facebook.login.LoginResult#d573369
D/GoogleActivity: handleFacebookAccessToken:{AccessToken token:ACCESS_TOKEN_REMOVED permissions:[public_profile, email]}
W/BiChannelGoogleApi: [FirebaseAuth: ] getGoogleApiForMethod() returned Gms: com.google.firebase.auth.api.internal.zzal#6703527
I/FirebaseAuth: [FirebaseAuth:] Loading module via FirebaseOptions.
[FirebaseAuth:] Preparing to create service connection to gms implementation
I've been looking around for this from quite some time and have not found anything which solves my problem.
I am using the following method for fb login, As per our knolwedge, we have tested all the boundary conditions & its working fine for us now and never faced any challenge yet.
//on click of fb button
private void handleFBLogin() {
AccessToken accessToken = AccessToken.getCurrentAccessToken();
LoginManager.getInstance().logOut();
boolean isLoggedIn = accessToken != null && !accessToken.isExpired();
LoginManager.getInstance().logInWithReadPermissions(ActivityLogin.this, Arrays.asList("public_profile", "email"));
LoginManager.getInstance().registerCallback(callbackManager,
new FacebookCallback<LoginResult>() {
#Override
public void onSuccess(final LoginResult loginResult) {
runOnUiThread(new Runnable() {
#Override
public void run() {
setFacebookData(loginResult, d);
}
});
}
#Override
public void onCancel() {
Toast.makeText(getApplicationContext(), "Canceled login ", Toast.LENGTH_SHORT); toast.show();
}
#Override
public void onError(FacebookException exception) {
d.dismiss();
if (exception instanceof FacebookAuthorizationException) {
if (AccessToken.getCurrentAccessToken() != null) {
LoginManager.getInstance().logOut();
handleFBLogin();
return;
}
}
Toast.makeText(getApplicationContext(), "ERROR " + exception.toString(), Toast.LENGTH_SHORT); toast.show();
PackageInfo info;
try {
info = getPackageManager().getPackageInfo([your package name], PackageManager.GET_SIGNATURES);
for (Signature signature : info.signatures) {
MessageDigest md;
md = MessageDigest.getInstance("SHA");
md.update(signature.toByteArray());
String something = new String(Base64.encode(md.digest(), 0));
//String something = new String(Base64.encodeBytes(md.digest()));
Log.e("hash key", something);
}
} catch (Exception e1) {
Log.e("name not found", e1.toString());
}
}
});
}
private void setFacebookData(final LoginResult loginResult) {
GraphRequest request = GraphRequest.newMeRequest(
loginResult.getAccessToken(),
new GraphRequest.GraphJSONObjectCallback() {
#Override
public void onCompleted(JSONObject object, GraphResponse response) {
try {
final String firstName = response.getJSONObject().getString("first_name");
String lastName = response.getJSONObject().getString("last_name");
String id = response.getJSONObject().getString("id");
String email = null;
if (response.getJSONObject().has("email"))
email = response.getJSONObject().getString("email");
//put your code here
} catch (JSONException e) {
e.printStackTrace();
}
}
});
Bundle parameters = new Bundle();
parameters.putString("fields", "id,email,first_name,last_name,gender");
request.setParameters(parameters);
request.executeAsync();
}
from this link it is clear that the access token cannot be see in logcat. thats why you are seeing token:ACCESS_TOKEN_REMOVED
the reason is, that you are mixing up Auth and mAuth in method handleFacebookAccessToken(AccessToken token).
the problem already introduces itself onCreate():
mAuth = FirebaseAuth.getInstance();
Auth = FirebaseAuth.getInstance();
remove Auth and use the instance called mAuth everywhere.
Try calling intent in onSuccess() method
#Override
public void onSuccess(LoginResult loginResult) {
Log.d(TAG2, "facebook:onSuccess:" + loginResult);
handleFacebookAccessToken(loginResult.getAccessToken());
setFbData(loginResult);
progressDialog.dismiss();
//call activity here
startActivity(new Intent(MainActivity.class));
}
In the debug mode you have to enable the logging for access token. So Add this lines
if (BuildConfig.DEBUG) {
FacebookSdk.setIsDebugEnabled(true);
FacebookSdk.addLoggingBehavior(LoggingBehavior.INCLUDE_ACCESS_TOKENS);
}
LoginManager.getInstance().registerCallback(callbackManager, new
FacebookCallback<LoginResult>() {
#Override
public void onSuccess(LoginResult loginResult) {
final GraphRequest request = GraphRequest.newMeRequest(loginResult.getAccessToken(), new GraphRequest.GraphJSONObjectCallback() {
#Override
public void onCompleted(JSONObject object, GraphResponse response) {
try {
if (object.has("id")) {
handleSignInResultFacebook(object); // Parse the json object for user details
} else {
Logger.e("FBLOGIN_FAILD", String.valueOf(object));
}
} catch (Exception e) {
e.printStackTrace();
dismissDialogLogin();
}
}
});
final Bundle parameters = new Bundle();
parameters.putString("fields", "name,email,id,picture.type(large)");
request.setParameters(parameters);
request.executeAsync();
}
#Override
public void onCancel() {
Logger.e("FBLOGIN_FAILD", "Cancel");
}
#Override
public void onError(FacebookException error) {
Logger.e("FBLOGIN_FAILD", "ERROR", error);
}
});
I'm writing an app that is supposed to connect to firebase database. Everything works fine, except the fact that when I check autenthication key (using getAuth() method), it always returns null. I use facebook for autenthication in my app, and I wanted to turn on autenthication on my database with:
{
"rules": {
".read": "auth != null",
".write":"auth != null"
}
}
My project has 2 classes, one is LoginActivity, that allows user to create account in database using Facebook account:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
firebaseAutenthication = FirebaseAuth.getInstance();
//Get current user ID
FirebaseUser mUser = firebaseAutenthication.getCurrentUser();
if (mUser != null) {
// Club is signed in
Intent intent = new Intent(getApplicationContext(), MainActivity.class);
String uid = firebaseAutenthication.getCurrentUser().getUid();
String image = firebaseAutenthication.getCurrentUser().getPhotoUrl().toString();
intent.putExtra("user_id", uid);
if (image != null || !Objects.equals(image, "")) {
intent.putExtra("profile_picture", image);
}
startActivity(intent);
finish();
Log.e(TAG, "onAuthStateChanged:signed_in:" + mUser.getUid());
}
//Setup firebase autenthication listener
firebaseAutenthicatorListener = new FirebaseAuth.AuthStateListener() {
#Override
public void onAuthStateChanged(#NonNull FirebaseAuth firebaseAuth) {
FirebaseUser mUser = firebaseAuth.getCurrentUser();
if (mUser != null) {
// Club is signed in
Log.e(TAG, "onAuthStateChanged:signed_in:" + mUser.getUid());
} else {
// Club is signed out
Log.e(TAG, "onAuthStateChanged:signed_out");
}
}
};
//Initialize facebook SDK
FacebookSdk.sdkInitialize(getApplicationContext());
if (BuildConfig.DEBUG) {
FacebookSdk.setIsDebugEnabled(true);
FacebookSdk.addLoggingBehavior(LoggingBehavior.INCLUDE_ACCESS_TOKENS);
}
//Create callback manager for facebook login
//onSucces calls login method
//TODO: onCancel and OnError should display popup with information that login failed
callbackManagerFromFacebook = CallbackManager.Factory.create();
LoginButton loginButton = (LoginButton) findViewById(R.id.button_facebook_login);
loginButton.setReadPermissions("email", "public_profile");
loginButton.registerCallback(callbackManagerFromFacebook, new FacebookCallback<LoginResult>() {
#Override
public void onSuccess(LoginResult loginResult) {
Log.e(TAG, "facebook:onSuccess:" + loginResult);
signInWithFacebook(loginResult.getAccessToken());
}
#Override
public void onCancel() {
Log.e(TAG, "facebook:onCancel");
}
#Override
public void onError(FacebookException error) {
Log.e(TAG, "facebook:onError", error);
}
});
}
#Override
protected void onStart() {
super.onStart();
firebaseAutenthication.addAuthStateListener(firebaseAutenthicatorListener);
}
#Override
public void onStop() {
super.onStop();
if (firebaseAutenthicatorListener != null) {
firebaseAutenthication.removeAuthStateListener(firebaseAutenthicatorListener);
}
}
//FaceBook
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
callbackManagerFromFacebook.onActivityResult(requestCode, resultCode, data);
}
private void signInWithFacebook(AccessToken token) {
Log.e(TAG, "signInWithFacebook:" + token);
showProgressDialog();
credential = FacebookAuthProvider.getCredential(token.getToken());
firebaseAutenthication.signInWithCredential(credential)
.addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull Task<AuthResult> task) {
Log.e(TAG, "signInWithCredential:onComplete:" + task.isSuccessful());
// If sign in fails, display a message to the user. If sign in succeeds
// the auth state listener will be notified and logic to handle the
// signed in user can be handled in the listener.
if (!task.isSuccessful()) {
Log.e(TAG, "signInWithCredential", task.getException());
Toast.makeText(LoginActivity.this, "Authentication failed.",
Toast.LENGTH_SHORT).show();
} else {
String uid = task.getResult().getUser().getUid();
String name = task.getResult().getUser().getDisplayName();
String email = task.getResult().getUser().getEmail();
Uri imageUri = task.getResult().getUser().getPhotoUrl();
String image = "";
if(imageUri != null) {
image = imageUri.toString();
}
//Create a new User and Save it in Firebase database
User user = new User(uid, name, null, email, null, null, "About Me");
firebaseUsers.child(uid).setValue(user);
//Start MainActivity and pass user data to it
Intent intent = new Intent(getApplicationContext(), MainActivity.class);
intent.putExtra("user_id", uid);
intent.putExtra("profile_picture", image);
startActivity(intent);
finish();
}
}
});
And 2nd one is MainActivity, supposed to get user information form his facebook profile and put them into the database:
void getValueFromFirebase() {
Log.e(TAG, "Started getValueFromFirebase()");
firebase.child(userID).child("name").addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
String data = dataSnapshot.toString();
Toast.makeText(getApplicationContext(), data, Toast.LENGTH_LONG).show();
}
#Override
public void onCancelled(FirebaseError firebaseError) {
Toast.makeText(getApplicationContext(), firebaseError.toString(), Toast.LENGTH_LONG).show();
}
});
}
void createFirebaseConnection() {
this.firebase = new Firebase(AppConstants.FIREBASE_URL_USERS);
this.firebaseAuthentication = FirebaseAuth.getInstance();
this.firebaseUser = firebaseAuthentication.getCurrentUser();
//Create listener for firebase autenthication
//Log if user is disconnected
this.firebaseAutenthicationStateListener = new FirebaseAuth.AuthStateListener() {
#Override
public void onAuthStateChanged(#NonNull FirebaseAuth firebaseAuth) {
FirebaseUser user = firebaseAuth.getCurrentUser();
if (user != null) {
// User is signed in
Log.e(TAG, "onAuthStateChanged:" + user.getUid());
} else {
// User is signed out
Log.d(TAG, "onAuthStateChanged: user is not signed in!");
}
}
};
firebaseAuthentication.addAuthStateListener(this.firebaseAutenthicationStateListener);
//Check if auth is done
//If not, autenthicate with Facebook Token
if(this.firebase.getAuth() == null) {
Log.e(TAG, "firebase.getAuth() == null, starting authWithFacebook()...");
authWithFacebook();
}
}
void authWithFacebook() {
Log.e(TAG, "authWithFacebook() started!");
AccessToken accessToken = AccessToken.getCurrentAccessToken();
AuthCredential credential = FacebookAuthProvider.getCredential(accessToken.getToken());
Log.e(TAG, "Facebook Token: " + accessToken.getToken());
Log.e(TAG, "Auth: " + firebase.getAuth());
}
void readDataFromLoginActivity() {
//Get the uid for the currently logged in Club from intent data passed to this activity
this.userID = getIntent().getExtras().getString("user_id");
//Get the imageUrl for the currently logged in Club from intent data passed to this activity
//Load image to ImageView
this.userImageUrl = getIntent().getExtras().getString("profile_picture");
}
#Override
public void onBackPressed() {
if (userProfile.moveState == 1) {
userProfile.slideBottom();
} else {
super.onBackPressed();
}
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.e(TAG, "onCreate() called...");
setContentView(R.layout.activity_main);
lay = (RelativeLayout) findViewById(R.id.lay);
Display display = getWindowManager().getDefaultDisplay();
Point size = new Point();
display.getSize(size);
width = size.x;
height = size.y;
Log.e(TAG, "readDataFromLoginActivity() called...");
readDataFromLoginActivity();
Log.e(TAG, "createFirebaseConnection() called...");
createFirebaseConnection();
}
#Override
protected void onStart() {
super.onStart();
Log.e(TAG, "onStart() called...");
addTopTabBar();
addProfileFragment();
addLeftSideBar();
Log.e(TAG, "Binding UI Elements...");
bindUIElements();
getValueFromFirebase();
}
Yet, the toast I display always shows "permission Error". How can I fix this?
You are using both the legacy 2.x.x SDK and the new 10.x.x SDK in the same app. This is not good practice and likely the source of the problem. Remove this line from your dependencies and make the needed code changes to use only the capabilities of the new SDK.
compile 'com.firebase:firebase-client-android:2.x.x'
The package names of the new SDK start with com.google.firebase. Those of the legacy SDK start with com.firebase.client.
Helpful tips are in the Upgrade Guide.
Currently, I am using this tutorial to create the facebook login.
"https://github.com/ParsePlatform/ParseUI-Android"
The Parse user JSON didn't return me an email or gender. I also have research around but I still can't find the solution (well, at least, some other still returning null). Anyone can explain the reason and how to solve it?
facebookLoginButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
loadingStart(false); // Facebook login pop-up already has a spinner
if (config.isFacebookLoginNeedPublishPermissions()) {
ParseFacebookUtils.logInWithPublishPermissionsInBackground(getActivity(),
Arrays.asList(
"public_profile", "email"), facebookLoginCallbackV4);
Log.i("fbUser","Publish");
} else {
ParseFacebookUtils.logInWithReadPermissionsInBackground(getActivity(),
Arrays.asList( "public_profile", "email"), facebookLoginCallbackV4);
Log.i("fbUser", "Read");
}
}
});
private LogInCallback facebookLoginCallbackV4 = new LogInCallback() {
#Override
public void done(ParseUser user, ParseException e) {
if (isActivityDestroyed()) {
return;
}
if (user == null) {
loadingFinish();
if (e != null) {
showToast(R.string.com_parse_ui_facebook_login_failed_toast);
debugLog(getString(R.string.com_parse_ui_login_warning_facebook_login_failed) +
e.toString());
}
} else if (user.isNew()) {
GraphRequest.newMeRequest(AccessToken.getCurrentAccessToken(),
new GraphRequest.GraphJSONObjectCallback() {
#Override
public void onCompleted(JSONObject fbUser,
GraphResponse response) {
/*
If we were able to successfully retrieve the Facebook
user's name, let's set it on the fullName field.
*/
ParseUser parseUser = ParseUser.getCurrentUser();
if (fbUser != null && parseUser != null && fbUser.optString("name").length() > 0) {
Log.i("FbUSer", response.getJSONObject().toString());
Log.d("FbUSer-Email",fbUser.optString("email"));
Log.i("FbUSer-gender",fbUser.optString("gender"));
parseUser.put(USER_OBJECT_NAME_FIELD, fbUser.optString("name"));
parseUser.saveInBackground(new SaveCallback() {
#Override
public void done(ParseException e) {
if (e != null) {
debugLog(getString(
R.string.com_parse_ui_login_warning_facebook_login_user_update_failed) +
e.toString());
}
loginSuccess();
}
});
}
loginSuccess();
}
}
).executeAsync();
} else {
loginSuccess();
}
}
};
Logcat Section return:
{"id":"1234524124124","name":"FbUser NAme"}
I just found the answer. I just need to set the parameter so I can get the data I want.
GraphRequest request = GraphRequest.newMeRequest(...);
Bundle parameters = new Bundle();
parameters.putString("fields","id,name,link,email,first_name,last_name,gender");
request.setParameters(parameters);
request.executeAsync();
Reference: https://stackoverflow.com/a/32579366/4961962
for more user info you have to add permissoin to access those detail like email, user_about_me at facebook developer console
select app at facebook developer and go -> app details -> Configure
App Center Permissions
I am using latest Facebook sdk for android in my applicaton.
public class MainActivity extends AppCompatActivity {
public static CallbackManager callbackmanager;
private AccessTokenTracker mTokenTracker;
private ProfileTracker mProfileTracker;
Button fb_login;
private boolean fb_signincllicked = false;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
FacebookSdk.sdkInitialize(getApplicationContext());
setContentView(R.layout.activity_main);
fb_login = (Button) findViewById(R.id.fb_login_button);
fb_login.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
onFblogin(true);
}
});
}
public void onFblogin(boolean fb_btn) {
fb_signincllicked = fb_btn;
callbackmanager = CallbackManager.Factory.create();
// setupTokenTracker();
// setupProfileTracker();
// mTokenTracker.startTracking();
// mProfileTracker.startTracking();
// Set permissions
LoginManager.getInstance().logInWithReadPermissions(this, Arrays.asList("public_profile", "email"));
LoginManager.getInstance().registerCallback(callbackmanager, new FacebookCallback<LoginResult>() {
#Override
public void onSuccess(LoginResult loginResult) {
// AccessToken accessToken = loginResult.getAccessToken();
// Profile profile = Profile.getCurrentProfile();
final Set<String> deniedPermissions = loginResult.getRecentlyDeniedPermissions();
GraphRequest.newMeRequest(loginResult.getAccessToken(), new GraphRequest.GraphJSONObjectCallback() {
#Override
public void onCompleted(JSONObject json, GraphResponse response) {
if (response.getError() != null) {
// handle error
} else {
try {
// if (deniedPermissions.contains("email")) {
// LoginManager.getInstance().logInWithReadPermissions(Login_Activity.this, Arrays.asList("email"));
// }
JSONObject jsonObject = new JSONObject();
if (jsonObject.has("picture")) {
String profilePicUrl = jsonObject.getJSONObject("picture").getJSONObject("data").getString("url");
System.out.println("111015:profilePicUrl" + profilePicUrl);
} else {
System.out.println("111015:profilePicUrl" + "No Data");
}
jsonObject.put("full_name", json.getString("name"));
Toast.makeText(getApplicationContext(), json.get("id").toString() + json.getString("name"), Toast.LENGTH_LONG).show();
jsonObject.put("device_id", Settings.Secure.getString(getContentResolver(), Settings.Secure.ANDROID_ID));
jsonObject.put("fb_id", json.getString("id"));
jsonObject.put("signuptype", "1");
Intent i = new Intent(getBaseContext(), Profile.class);
i.putExtra("prof_name", json.getString("name"));
i.putExtra("fb_id", json.getString("id"));
startActivity(i);
} catch (JSONException e) {
e.printStackTrace();
}
}
}
}).executeAsync();
}
#Override
public void onCancel() {
Log.d("Cancel", "On cancel");
}
#Override
public void onError(FacebookException error) {
Log.d("Error", error.toString());
}
});
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (fb_signincllicked) {
callbackmanager.onActivityResult(requestCode, resultCode, data);
}
}
#Override
public void onStop() {
super.onStop();
// mTokenTracker.stopTracking();
// mProfileTracker.stopTracking();
}
// private void setupTokenTracker() {
// mTokenTracker = new AccessTokenTracker() {
// #Override
// protected void onCurrentAccessTokenChanged(AccessToken oldAccessToken, AccessToken currentAccessToken) {
// Log.d("VIVZ", "" + currentAccessToken);
// }
// };
// }
//
// private void setupProfileTracker() {
// mProfileTracker = new ProfileTracker() {
// #Override
// protected void onCurrentProfileChanged(Profile oldProfile, Profile currentProfile) {
// Log.d("VIVZ", "" + currentProfile);
// }
// };
// }
}
After success full login(which succeeded) i want to go to another activity.There i want to show the following,
Facebook profile picture in a custom image view(not in the image
view which Facebook provided).
Primary-Email
Phone Number(If user provided in Face Book)
Facebook link of the user.
Please help me. Thanks in advance.
On your onActivityCreated() put this code :
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
updateWithToken(AccessToken.getCurrentAccessToken());
}
then here is my code which i'm currently using it to make facebook login :
private void updateWithToken(AccessToken currentAccessToken) {
mTokenTracker.startTracking();
mProfileTracker.startTracking();
if (currentAccessToken != null) {
String accessToken = currentAccessToken
.getToken();
Log.i("accessToken", accessToken);
GraphRequest request = GraphRequest.newMeRequest(
currentAccessToken,
new GraphRequest.GraphJSONObjectCallback() {
#Override
public void onCompleted(JSONObject object,
GraphResponse response) {
Log.i("LoginActivity",
response.toString());
try {
String id = object.getString("id");
try {
URL profile_pic = new URL(
"http://graph.facebook.com/" + id + "/picture?type=large");
Log.i("profile_pic",
profile_pic + "");
} catch (MalformedURLException e) {
e.printStackTrace();
}
if (!sessionManagerFacebook.isLoggedIn()) {
sessionManagerFacebook.createLoginSession(object.getString("email"), getResources().getConfiguration().locale.toString());
if (cameFromQuestionExtra != null && cameFromQuestionExtra.getString("cameFromQuestion").equals("yes")) {
getActivity().setResult(1);
getActivity().finish();
}
//startActivity(new Intent(getActivity(), MainActivity.class));
} else {
user = sessionManagerFacebook.getUserDetails();
startActivity(new Intent(getActivity(), MainActivity.class));
}
getActivity().finish();
} catch (JSONException e) {
e.printStackTrace();
}
}
});
Bundle parameters = new Bundle();
parameters.putString("fields",
"id,name,email,gender");
request.setParameters(parameters);
request.executeAsync();
}
}
And on your second activity u just have to make new profile variable :
Profile profile = Profile.getCurrentProfile();
if (profile != null) {
Toast.makeText(MainActivity.this, profile.getName(), Toast.LENGTH_SHORT).show();
loadImages(profile.getProfilePictureUri(120, 120).toString());
profileName.setText(profile.getName());
mDrawer.getMenu().findItem(R.id.nav_myAccount).setVisible(false);
Bundle extra = getIntent().getExtras();
String email;
if (extra != null) {
email = extra.getString("email");
profileEmail.setText(email);
Toast.makeText(MainActivity.this, email, Toast.LENGTH_SHORT).show();
} else if (sessionManagerFacebook.isLoggedIn()) {
profileEmail.setText(userFacebook.get(SessionManagerFacebook.KEY_EMAIL));
Toast.makeText(MainActivity.this, userFacebook.get(SessionManagerFacebook.KEY_EMAIL), Toast.LENGTH_SHORT).show();
}
}
https://developers.facebook.com/docs/reference/android/current/class/Profile/