I have added Firebase Auth in my android app and I am using Facebook and Google sign in. Signing in is working fine. Now I want to retrieve user profile info from user's either Facebook account or Google account (whichever, user chooses to sign in) and display the info in user profile activity. I am able to retrieve and display user name and user UID, however, user email and user photo are not displaying, though retrieved.
Here is how I am retrieving user info (LoginActivity.java):
authStateListener = new FirebaseAuth.AuthStateListener() {
#Override
public void onAuthStateChanged(#NonNull FirebaseAuth firebaseAuth) {
FirebaseUser user = firebaseAuth.getCurrentUser();
if (user != null) {
//User is signed in
for (UserInfo userInfo : user.getProviderData()){
String user_name = userInfo.getDisplayName();
String user_email = userInfo.getEmail();
Uri user_img = userInfo.getPhotoUrl();
String user_id = userInfo.getUid();
SharedPreferences preferences = getSharedPreferences(UserInfoConstants.STRING_NAME,0);
SharedPreferences.Editor editor = preferences.edit();
editor.putString(UserInfoConstants.KEY_USER_NAME, user_name);
editor.putString(UserInfoConstants.KEY_USER_EMAIL, user_email);
editor.putString(UserInfoConstants.KEY_USER_ID, user_id);
editor.putString(UserInfoConstants.KEY_USER_IMG, user_img != null ? user_img.toString() : null);
editor.apply();
}
} else {
//User is signed out
return;
}
}
};
Here is how am displaying user info (ProfileActivity.java):
SharedPreferences preferences = getSharedPreferences(LoginActivity.UserInfoConstants.STRING_NAME,0);
String user_img_uri = preferences.getString(LoginActivity.UserInfoConstants.KEY_USER_IMG,"");
if (user_img_uri.isEmpty()){
userImgView.setImageResource(R.drawable.com_facebook_profile_picture_blank_portrait);
} else {
userImgView.setImageBitmap(getImageBitmap(user_img_uri));
}
userName.setText(preferences.getString(LoginActivity.UserInfoConstants.KEY_USER_NAME,""));
userEmail.setText(preferences.getString(LoginActivity.UserInfoConstants.KEY_USER_EMAIL,""));
userId.setText("ID: " + preferences.getString(LoginActivity.UserInfoConstants.KEY_USER_ID,""));
I searched a lot about it but is unable to get any resolution for the same.
Can anyone help????
Uri refrence is always null. Try to store it as string like this:
String uri = userInfo.getPhotoUrl().toString;
And pass it to preference, then set it like this:
String fbImage = pref.getString("ImageUri", "");
if (fbImage != null && !fbImage.isEmpty()) {
Picasso.with(getApplicationContext())
.load(fbImage)
.placeholder(R.drawable.img_circle_placeholder)
.resize(avatarSize, avatarSize)
.centerCrop()
.transform(new CircleTransformation())
.into(ImageViewObject);
}
Make sure you added picasso dependency to your gradle.
compile 'com.squareup.picasso:picasso:2.3.2'
for emailID:
String email = pref.getString("email", null);
//try to check here
Log.w("email", ""+email);
if(email != null && !email.isEmpty()){
textEmail.setText(""+email);
}
or you can use intent service this is work for sure:
In you login activity:
Intent intent = new Intent(this, MainActivity.class);
intent.putExtra("email_id", email_id);
startActivity(intent);
finish();
and in your mainActivity:
Intent intent = getIntent();
String email = intent.getStringExtra("email_id");
textEmail.setText(""+email);
update-2
there is one firebase method.. and its easiest way to do it.
write this code in your second activity where you want to retrive data..
FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
TextView email;
email.setText(""+ user.getEmail());
there is no need of sharedPrefrence or intent service.
Related
I am trying to create a very simple login with Facebook using firebase and android studio. My login with Facebook works and I was able to run the app and sign in but none of my info has been stored in firebase (I want to have the persons name, email, etc.) I know it's something small I am probably missing but I cannot figure it out and I have tried so many things. Also I checked and all my gradle files are up to date and my firebase is set up correctly so it has nothing to do with that. plz help.
firebaseAuth = FirebaseAuth.getInstance();
firebaseAuthListner = new FirebaseAuth.AuthStateListener(){
#Override
public void onAuthStateChanged(#NonNull FirebaseAuth firebaseAuth) {
FirebaseUser user = firebaseAuth.getCurrentUser();
if(user != null){
// what do i put here to pull out the fb users info into firebase?!
goMainScreen();
}
}
};
I have tried:
if(user != null){
String name = user.getDisplayName();
String email = user.getEmail();
String uid = user.getUid();
I have tried:
if (user != null) {
// User is signed in
Log.d(TAG, "onAuthStateChanged:signed_in:" + user.getUid());
} else {
// User is signed out
Log.d(TAG, "onAuthStateChanged:signed_out");
}
I know it is probably a dumb mistake because I am new to firebase and android studio but any advice will help. Thank you
Are your user stored into the firebase console? (https://console.firebase.google.com)
If it is not stored in your project, it will not return anything when you call the getDisplayName(), getUser(), etc.
If they are stored, please post the complete code that you are using to do the login.
I am currently working on an app using android studio and currently have a working login using Firebase user authentication. However, I am trying to have an image appear on the screen when the user logs after using this authentication. I want this image to be linked to that specific user. Is this possible?
You can set a photo url on a user's firebase profile with the following code:
FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
UserProfileChangeRequest profileUpdates = new UserProfileChangeRequest.Builder()
.setDisplayName("Jane Q. User")
.setPhotoUri(Uri.parse("https://example.com/jane-q-user/profile.jpg"))
.build();
user.updateProfile(profileUpdates)
.addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
if (task.isSuccessful()) {
Log.d(TAG, "User profile updated.");
}
}
});
You would then retrieve the user's profile information (including their photo URL) like so:
FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
if (user != null) {
// Name, email address, and profile photo Url
String name = user.getDisplayName();
String email = user.getEmail();
Uri photoUrl = user.getPhotoUrl();
// Check if user's email is verified
boolean emailVerified = user.isEmailVerified();
// The user's ID, unique to the Firebase project. Do NOT use this value to
// authenticate with your backend server, if you have one. Use
// FirebaseUser.getToken() instead.
String uid = user.getUid();
}
More info: https://firebase.google.com/docs/auth/android/manage-users
If you're using oAuth authentication and want to retrieve their profile photo from facebook, you'll find more information about how to do that at the link below:
https://firebase.google.com/docs/auth/android/facebook-login
I am using FirebaseAuth to login user through FB. Here is the code:
private FirebaseAuth mAuth;
private FirebaseAuth.AuthStateListener mAuthListener;
private CallbackManager mCallbackManager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
FacebookSdk.sdkInitialize(getApplicationContext());
// Initialize Firebase Auth
mAuth = FirebaseAuth.getInstance();
mAuthListener = firebaseAuth -> {
FirebaseUser user = firebaseAuth.getCurrentUser();
if (user != null) {
// User is signed in
Log.d(TAG, "onAuthStateChanged:signed_in:" + user.getUid());
} else {
// User is signed out
Log.d(TAG, "onAuthStateChanged:signed_out");
}
if (user != null) {
Log.d(TAG, "User details : " + user.getDisplayName() + user.getEmail() + "\n" + user.getPhotoUrl() + "\n"
+ user.getUid() + "\n" + user.getToken(true) + "\n" + user.getProviderId());
}
};
}
The issue is that the photo in I get from using user.getPhotoUrl() is very small. I need a larger image and can't find a way to do that. Any help would be highly appreciated.
I have already tried this
Get larger facebook image through firebase login
but it's not working although they are for swift I don't think the API should differ.
It is not possible to obtain a profile picture from Firebase that is larger than the one provided by getPhotoUrl(). However, the Facebook graph makes it pretty simple to get a user's profile picture in any size you want, as long as you have the user's Facebook ID.
String facebookUserId = "";
FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
ImageView profilePicture = (ImageView) findViewById(R.id.image_profile_picture);
// find the Facebook profile and get the user's id
for(UserInfo profile : user.getProviderData()) {
// check if the provider id matches "facebook.com"
if(FacebookAuthProvider.PROVIDER_ID.equals(profile.getProviderId())) {
facebookUserId = profile.getUid();
}
}
// construct the URL to the profile picture, with a custom height
// alternatively, use '?type=small|medium|large' instead of ?height=
String photoUrl = "https://graph.facebook.com/" + facebookUserId + "/picture?height=500";
// (optional) use Picasso to download and show to image
Picasso.with(this).load(photoUrl).into(profilePicture);
Two lines of code. FirebaseUser user = firebaseAuth.getCurrentUser();
String photoUrl = user.getPhotoUrl().toString();
photoUrl = photoUrl + "?height=500";
simply append "?height=500" at the end
If someone is looking for this but for Google account using FirebaseAuth. I have found a workaround for this. If you detail the picture URL:
https://lh4.googleusercontent.com/../.../.../.../s96-c/photo.jpg
The /s96-c/ specifies the image size (96x96 in this case)so you just need to replace that value with the desired size.
String url= FirebaseAuth.getInstance().getCurrentUser().getPhotoUrl();
url = url.replace("/s96-c/","/s300-c/");
You can analyze your photo URL to see if there is any other way to change its size.
As I said in the begining, this only works for Google accounts. Check #Mathias Brandt 's answer to get a custom facebook profile picture size.
EDIT 2020:
Thanks to Andres SK and #alextouzel for pointing this out. Photo URLs format have changed and now you can pass URL params to get different sizes of the picture. Check https://developers.google.com/people/image-sizing.
photoUrl = "https://graph.facebook.com/" + facebookId+ "/picture?height=500"
You can store this link to firebase database with user facebookId and use this in app.
Also you can change height as a parameter
Not for Android, but for iOS, but I thought it could be helpful for other people (I didn't find a iOS version of this question).
Based the provided answers I created a Swift 4.0 extension that adds a function urlForProfileImageFor(imageResolution:) to the Firebase User object. You can either ask for the standard thumbnail, a high resolution (I put this to 1024px but easily changed) or a custom resolution image. Enjoy:
extension User {
enum LoginType {
case anonymous
case email
case facebook
case google
case unknown
}
var loginType: LoginType {
if isAnonymous { return .anonymous }
for userInfo in providerData {
switch userInfo.providerID {
case FacebookAuthProviderID: return .facebook
case GoogleAuthProviderID : return .google
case EmailAuthProviderID : return .email
default : break
}
}
return .unknown
}
enum ImageResolution {
case thumbnail
case highres
case custom(size: UInt)
}
var facebookUserId : String? {
for userInfo in providerData {
switch userInfo.providerID {
case FacebookAuthProviderID: return userInfo.uid
default : break
}
}
return nil
}
func urlForProfileImageFor(imageResolution: ImageResolution) -> URL? {
switch imageResolution {
//for thumnail we just return the std photoUrl
case .thumbnail : return photoURL
//for high res we use a hardcoded value of 1024 pixels
case .highres : return urlForProfileImageFor(imageResolution:.custom(size: 1024))
//custom size is where the user specified its own value
case .custom(let size) :
switch loginType {
//for facebook we assemble the photoUrl based on the facebookUserId via the graph API
case .facebook :
guard let facebookUserId = facebookUserId else { return photoURL }
return URL(string: "https://graph.facebook.com/\(facebookUserId)/picture?height=\(size)")
//for google the trick is to replace the s96-c with our own requested size...
case .google :
guard var url = photoURL?.absoluteString else { return photoURL }
url = url.replacingOccurrences(of: "/s96-c/", with: "/s\(size)-c/")
return URL(string:url)
//all other providers we do not support anything special (yet) so return the standard photoURL
default : return photoURL
}
}
}
}
Note: From Graph API v8.0 you must provide the access token for every UserID request you do.
Hitting the graph API:
https://graph.facebook.com/<user_id>/picture?height=1000&access_token=<any_of_above_token>
With firebase:
FirebaseUser user = mAuth.getCurrentUser();
String photoUrl = user.getPhotoUrl() + "/picture?height=1000&access_token=" +
loginResult.getAccessToken().getToken();
You get the token from registerCallback just like this
LoginManager.getInstance().registerCallback(mCallbackManager, new FacebookCallback<LoginResult>() {
#Override
public void onSuccess(LoginResult loginResult) {
FirebaseUser user = mAuth.getCurrentUser();
String photoUrl = user.getPhotoUrl() + "/picture?height=1000&access_token=" + loginResult.getAccessToken().getToken();
}
#Override
public void onCancel() {
Log.d("Fb on Login", "facebook:onCancel");
}
#Override
public void onError(FacebookException error) {
Log.e("Fb on Login", "facebook:onError", error);
}
});
This is what documentation says:
Beginning October 24, 2020, an access token will be required for all
UID-based queries. If you query a UID and thus must include a token:
use a User access token for Facebook Login authenticated requests
use a Page access token for page-scoped requests
use an App access token for server-side requests
use a Client access token for mobile or web client-side requests
We recommend that you only use a Client token if you are unable to use
one of the other token types.
I use this code in a Second Activity, after having already logged in, for me the Token that is obtained in loginResult.getAccessToken().getToken(); It expires after a while, so researching I found this and it has served me
final String img = mAuthProvider.imgUsuario().toString(); // is = mAuth.getCurrentUser().getPhotoUrl().toString;
final String newToken = "?height=1000&access_token=" + AccessToken.getCurrentAccessToken().getToken();
Picasso.get().load(img + newToken).into("Image reference");
Check below response
final graphResponse = await http.get(
'https://graph.facebook.com/v2.12/me?fields=name,picture.width(800).height(800),first_name,last_name,email&access_token=${fbToken}');
Hi I am trying to use the Parse Api's database for my project which requires user accounts that Parse provides. While I was reading the tutorial on how to set up user accounts at
https://parse.com/docs/android_guide#users it stated:
"Enabling email verification in an application's settings allows the application to reserve part of its experience for users with confirmed email addresses. Email verification adds the emailVerified key to the ParseUser object. When a ParseUser's email is set or modified, emailVerified is set to false. Parse then emails the user a link which will set emailVerified to true."
How exactly would you add the emailVerification key = true whenever a user tries to register:
ParseUser user = new ParseUser();
user.setUsername(username);
user.setPassword(password);
user.setEmail(email);
user.signUpInBackground(new SignUpCallback() {
public void done(ParseException e) {
if (e == null) {
// sign up succeeded so go to multiplayer screen
// store the username of the current player
currentUser = username;
final String title = "Account Created Successfully!";
final String message = "Please verify your email before playing";
buildAlertDialog(title, message, true);
} else {
// sign up didnt succed. //TODO: figure out how do deal with error
final String title = "Error Account Creation failed";
final String message = "Account could not be created";
buildAlertDialog(title, message, false);
}
}
});
Go to your parse.com dashboard, go to settings, email settings and switch on the Verify user emails.
No code required.
My app I'm developing launches the official twitter app new post screen so the user can post a tweet with some extra text added in the intent. I have got this working nicely however things get a little confused if the user is not logged in with the twitter app. The app launches but the user has to sign in, once they've done that the normal twitter screen appears, if they use the back button to get back to my app the new post screen actually appears after hitting back on the twitter feed screen.
Is there any way I can check that a user is actually signed into the twitter app before trying to run the intent?
I think it's a Twitter app internal issue and you can't test for it.
On the other hand you could provide a Dialog warning the user for this matter with a "Do not show this dialog anymore" checkbox so he gets advised and can dimiss forever the Dialog. You could even provide instructions to authenticate insside the Twitter app in this Dialog.
I am using twitter4j lib.
Here I check for the username. If the username is null then there is no user signed in , else I get the username. This user name is available in the access token which I store in shared preference.
username= mySession.getUsername();
username = (username.equals("")) ? "Not logged in" : username;
code for mySession :-
public class MySession {
private SharedPreferences sharedPref;
private Editor editor;
private static final String TWEET_AUTH_KEY = "auth_key";
private static final String TWEET_AUTH_SECRET_KEY = "auth_secret_key";
private static final String TWEET_USER_NAME = "user_name";
private static final String SHARED = "Twitter_Preferences";
public TwitterSession(Context context) {
sharedPref = context.getSharedPreferences(SHARED, Context.MODE_PRIVATE);
editor = sharedPref.edit();
}
public void storeAccessToken(AccessToken accessToken, String username) {
editor.putString(TWEET_AUTH_KEY, accessToken.getToken());
editor.putString(TWEET_AUTH_SECRET_KEY, accessToken.getTokenSecret());
editor.putString(TWEET_USER_NAME, username);
editor.commit();
}
public void resetAccessToken() {
editor.putString(TWEET_AUTH_KEY, null);
editor.putString(TWEET_AUTH_SECRET_KEY, null);
editor.putString(TWEET_USER_NAME, null);
editor.commit();
}
public String getUsername() {
return sharedPref.getString(TWEET_USER_NAME, "");
}
public AccessToken getAccessToken() {
String token = sharedPref.getString(TWEET_AUTH_KEY, null);
String tokenSecret = sharedPref.getString(TWEET_AUTH_SECRET_KEY, null);
if (token != null && tokenSecret != null)
return new AccessToken(token, tokenSecret);
else
return null;
}
}
Hope this will help you.
Try this function which will in turn returns you true or false.
True : Logged in
False : Not logged in
twitter.getAuthorization() function will throw you an error if it is not logged in by handling this you can find whether user is previously logged in or not.
public static boolean isAuthenticated(SharedPreferences prefs) {
String token = prefs.getString(OAuth.OAUTH_TOKEN, "");
String secret = prefs.getString(OAuth.OAUTH_TOKEN_SECRET, "");
AccessToken a = new AccessToken(token,secret);
Twitter twitter = new TwitterFactory().getInstance();
twitter.setOAuthConsumer(Constants.CONSUMER_KEY, Constants.CONSUMER_SECRET);
try {
twitter.getAuthorization();
return true;
} catch (Exception e) {
return false;
}
}
just add these lines in the oncreate() in ur activity
final Session activeSession = Twitter.getInstance().core.getSessionManager().getActiveSession();
if (activeSession != null){
//do someting
}