25

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.

Neeraj Sewani
  • 3,952
  • 6
  • 38
  • 55
Gaurav Sarma
  • 2,248
  • 2
  • 24
  • 45
  • See http://stackoverflow.com/questions/38032124/get-larger-facebook-image-through-firebase-login – Frank van Puffelen Aug 23 '16 at 13:10
  • @FrankvanPuffelen i have tried those answer and it didn't work + its for swift although the API should be similar but still its not working could you please remove your review – Gaurav Sarma Aug 24 '16 at 08:10
  • The approach to get such information is the same on every platform. If you have tried the approach outlined there, share what you've tried. – Frank van Puffelen Aug 24 '16 at 15:52
  • As i have shared in the code above i am using the FirebaseAuthListener and i get the following url with the user.getPhotoUrl() https://scontent.xx.fbcdn.net/v/t1.0-1/p100x100/10922641_923364564340516_5806691876435358366_n.jpg?oh=04d7f4ce865da066202842d687072ecf&oe=58455954 – Gaurav Sarma Aug 24 '16 at 16:24
  • @FrankvanPuffelen Did it work for you ? Waiting for your king response – Gaurav Sarma Aug 24 '16 at 19:06
  • Hmmm... I can't get Facebook auth to work on my device at the moment. Re-opened in hopes somebody else can chime in. – Frank van Puffelen Aug 25 '16 at 01:25

8 Answers8

47

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);
madx
  • 6,723
  • 4
  • 55
  • 59
mfb
  • 833
  • 10
  • 14
  • Although i had already found the answer thanks for posting it here i hope it helps other who are looking for the same solution. Please upvote the question i have accepted your answer. Thanks @Mathias – Gaurav Sarma Aug 31 '16 at 18:32
  • what is facebook_provider_id? Is it facebook_app_id? – Yunus Haznedar Apr 06 '17 at 15:09
  • facebook_provider_id is simply "facebook.com". I put it in Strings.xml so I could easily change it if Firebase decided to change it later for whatever reason. – mfb Apr 06 '17 at 15:52
  • Sir, I'm getting "Target must not be null" error. Could you check out this:http://stackoverflow.com/questions/43260782/cant-get-fb-profile-picture-with-firebase – Yunus Haznedar Apr 06 '17 at 17:38
  • In latest Facebook API v3.3, the valid parameters for type values has changed **The size of this picture. It can be one of the following values: small, normal, large, square.** – li_developer Jun 17 '19 at 17:34
33

Two lines of code. FirebaseUser user = firebaseAuth.getCurrentUser();

String photoUrl = user.getPhotoUrl().toString();
        photoUrl = photoUrl + "?height=500";

simply append "?height=500" at the end

Soropromo
  • 1,212
  • 12
  • 17
16

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.

Sebastiandg7
  • 1,175
  • 1
  • 15
  • 22
  • Update: this doesn't seem to work in 2020. Now you get urls like `https://lh3.googleusercontent.com/a-/AOh14Gg2pCyl90sYWeqrm4jTC2xI3o0CFUzK_x7-PcmC3rA` – Andres SK May 04 '20 at 14:06
  • 1
    @AndresSK We can now append different params to the URL to get different sizes. To get the size you want, you simply add "=s200" where 200 is the size. See the following link for all options: [https://developers.google.com/people/image-sizing](https://developers.google.com/people/image-sizing) – alextouzel Jul 17 '20 at 04:11
2
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

Dmitriy
  • 5,525
  • 12
  • 25
  • 38
2

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
            }
        }
    }

}
HixField
  • 3,538
  • 1
  • 28
  • 54
2

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.

Gmacv
  • 383
  • 3
  • 6
2

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");
Boken
  • 4,825
  • 10
  • 32
  • 42
JEDD
  • 31
  • 3
0

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}');
Jewel Rana
  • 2,397
  • 1
  • 19
  • 28