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}');
Related
I might me doing something wrong. I managed to get the facebook image with user.getPhotoUrl but it only shows a low res picture.
So I tried using this code.
FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
if (user != null) {
String name = user.getDisplayName();
nameView.setText(user.getDisplayName());
Picasso.with(this).load("https://graph.facebook.com/"+user.getUid()+"/picture?type=large").into(profileImage);
}
What am I doing wrong here?
Use this link to get a picture of a quality that you want. Just replace width=200 with the width you want and height=200 with the height you want.
"https://graph.facebook.com/"+user.getUid()+"/picture?type=large&width=200&height=200"
I managed to do it!
for(UserInfo profile : user.getProviderData()) {
if(profile.getProviderId().equals(getString("facebook.com"))) {
facebookUserId = profile.getUid();
}
}
String photoUrl = "https://graph.facebook.com/" + facebookUserId + "/picture?height=500";
Picasso.with(this).load(photoUrl).into(profileImage);
This worked for me
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 developing an Android App using Firebase, In my app I am using Firebase Anonymous Login and Google sign In.
When the application starts if the user is not Logged In, then I am using Anonymous Authentication to log the user in.
Afterwards when user chooses to Sign In using Google, then I am converting Anonymous Account to a permanent account.
My issue over here is, When user's account is converted from Anonymous Account to permanent account (using Google Sign In in this case), I am not getting User's Display Name and Photo Url.
For converting from Anonymous Account to permanent account I am using below code.
AuthCredential credential = GoogleAuthProvider.getCredential(googleIdToken, null);
mAuth.getCurrentUser().linkWithCredential(credential)
.addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull Task<AuthResult> task) {
Log.d(TAG, "linkWithCredential:onComplete:" + task.isSuccessful());
if (!task.isSuccessful()) {
Toast.makeText(AnonymousAuthActivity.this, "Authentication failed.",Toast.LENGTH_SHORT).show();
//If Google Account already linked up with other UID
Tasks.await(mAuth.signInWithCredential(credential)).getUser();
}
}
});
After the Sign In process completes, the AuthStateListener onAuthStateChanged is called, Then in onAuthStateChanged I am extracting User's Display Name, User's Photo Url and User's Email. Below is the onAuthStateChanged code.
#Override
public void onAuthStateChanged(#NonNull FirebaseAuth firebaseAuth) {
FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
if (user != null && !(user.isAnonymous())) {
Log.d("userDetails", "UID: " + user.getUid());
Log.d("userDetails", "Name: " + user.getDisplayName());
Log.d("userDetails", "PhotoUrl: " + user.getPhotoUrl().toString());
Log.d("userDetails", "Email: " + user.getEmail());
}
In the log I am getting null for user.getDisplayName() and user.getPhotoUrl()
I don't understand what I am doing wrong. Please help.
Thanks & Regards,
FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
user.getProviderData();
loop through providers and get the desired provider
userData.getProviderId().equals(GoogleAuthProvider.PROVIDER_ID)
Uri photoUrl = userData.getPhotoUrl();
When linking accounts (or even on every sign in), call this function
Future<void> updateMissingUserPropertise(User user) async {
if (user.photoURL == null) await user.updatePhotoURL(user.providerData[0].photoURL);
if (user.displayName == null) await user.updateDisplayName(user.providerData[0].displayName);
}
In order to support multiple providers, each of which might hold a different name, photo, or phone number, Firebase auth does not modify the user properties when linking accounts.
Even if the user signs out later and signs in with Google, or any other federated account, it does not change the user properties.
The function above 'fixes' the missing user properties by grabbing them from the first provider, which is Google in your case, and setting them in the user properties for good.
The more complex version of this function, which supports the case of multiple providers, loops through the providers until a DisplayName or a photoURL are found.
Future<void> updateMissingUserPropertise(User user) async {
if (user.photoURL == null) {
user.providerData.forEach((provider) async {
if (provider.photoURL != null) {
await user.updatePhotoURL(provider.photoURL);
return;
}
});
}
if (user.displayName == null) {
user.providerData.forEach((provider) async {
if (provider.displayName != null) {
await user.updateDisplayName(provider.displayName);
return;
}
});
}
}
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.
Am trying to display the profile picture of users logged into my app through Google+ but am not sure how to do this.To get the image (and other information), google provides the code
#Override
public void onConnected() {
...
if (mPlusClient.getCurrentPerson() != null) {
Person currentPerson = mPlusClient.getCurrentPerson();
String personName = currentPerson.getDisplayName();
String personPhoto = currentPerson.getImage();
String personGooglePlusProfile = currentPerson.getUrl();
}
}
I am aware that ordinarily i would need to get any image i want to display from res/drawable... but i don't know what to do with the value of personPhoto (which somehow get's changed from type String to Image when you paste the code in Eclipse.
You need to use that URL to grab the photo as a bitmap and set it to an imageview.
Section 4.9 of this article explains how to make an asynctask that will do just that:
http://www.androidhive.info/2014/02/android-login-with-google-plus-account-1/
First you need to add this dependency in your app/build.gradle file:
dependencies {compile 'com.github.bumptech.glide:glide:3.8.0'}
After this update your UI Accordingly :
private void updateUI(GoogleSignInAccount account) {
if (account != null){
text.setText("Sign in as :" +account.getDisplayName());
email.setText(account.getEmail());
String imgurl = account.getPhotoUrl().toString();
Glide.with(this).load(imgurl).into(profile);
sighIn.setVisibility(View.GONE);
sighOut.setVisibility(View.VISIBLE);
}
else {
text.setText("signOut");
sighIn.setVisibility(View.VISIBLE);
sighOut.setVisibility(View.GONE);
}
}
This is the solution that worked on my Android app. I developed it from an answer above by Naveen Kumar Yadav.
Prerequisites
- I am using a Google Sign-In API for my login.
- I have an XML Code with an ImageView that has an id "client_dp"
Add this dependency to your app-level build.gradle file
dependencies {compile 'com.github.bumptech.glide:glide:3.8.0'}
Then add this code to your activity java file
//Firebase get user info
firebaseAuth = FirebaseAuth.getInstance();
FirebaseUser account = firebaseAuth.getCurrentUser();
if (account != null){
//Display User Image from Google Account
//Objects.requireNonNull() prevents getPhotoUrl() from returning a NullPointerException
String personImage = Objects.requireNonNull(account.getPhotoUrl()).toString();
ImageView userImage = findViewById(R.id.client_dp);
Glide.with(this).load(personImage).into(userImage);
}
With new google sign in Options in Kotlin. Simply request for the parameters you need in your onCreate function
val gso =
GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
.requestIdToken(getString("your-client-id"))
.requestEmail()
.requestProfile()
.requestId()
.build()
When recieving back the response from google Sign in activity, inside the
Get user profile picture through:
val credential = GoogleAuthProvider.getCredential(account?.idToken, null)
val photoUrl = credential.photoUrl.toString()