skip to Main Content

I am using Firebase Authentication for my Android app. Users have the ability to login with multiple providers (Google, Facebook, Twitter).

After a successful login, is there a way to get the user gender/birth date from these providers using the Firebase api?

4

Answers


  1. No, you can’t get these data directly. But you can use the id of the user and get these data from various providers. Please check before what are the data that are available in the public API for each of these providers for instance google just deprecated few methods from the peopleApi.

    Anyways here is what i do for facebook

    // Initialize Firebase Auth
    FirebaseAuth mAuth = FirebaseAuth.getInstance();
    
    // Create a listener
    FirebaseAuth.AuthStateListener 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());
    
                String userId = user.getUid(); 
                String displayName = user.getDisplayName();
                String photoUrl = String.valueOf(user.getPhotoUrl());
                String email = user.getEmail();
    
                Intent homeIntent = new Intent(LoginActivity.this, HomeActivity.class);
                startActivity(homeIntent);
                finish();
            }
        };
    
    //Initialize the fB callbackManager
    mCallbackManager = CallbackManager.Factory.create();
    

    And do the following inside the onClick of the FB login button

    LoginManager.getInstance().registerCallback(mCallbackManager,
                new FacebookCallback<LoginResult>() {
                    @Override
                    public void onSuccess(LoginResult loginResult) {
                        Log.d(TAG, "facebook:onSuccess:" + loginResult);
                        handleFacebookAccessToken(loginResult.getAccessToken());
                    }
    
                    @Override
                    public void onCancel() {
                        Log.d(TAG, "facebook:onCancel");
                    }
    
                    @Override
                    public void onError(FacebookException error) {
                        Log.d(TAG, "facebook:onError", error);
                    }
                });
    
    LoginManager.getInstance().logInWithReadPermissions(this, Arrays.asList("public_profile", "email"));
    
    Login or Signup to reply.
  2. Unfortunately, Firebase doesn’t have any built-in functionality to get the user’s gender/birthdate upon successful login. You would have to retrieve these data from each of the providers yourself.

    Here is how you might get the user’s gender from Google using Google People API

    public class SignInActivity extends AppCompatActivity implements
            GoogleApiClient.ConnectionCallbacks,
            GoogleApiClient.OnConnectionFailedListener,
            View.OnClickListener {
        private static final int RC_SIGN_IN = 9001;
    
        private GoogleApiClient mGoogleApiClient;
    
        private FirebaseAuth mAuth;
        private FirebaseAuth.AuthStateListener mAuthListener;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_google_sign_in);
    
            // We can only get basic information using FirebaseAuth
            mAuth = FirebaseAuth.getInstance();
            mAuthListener = new FirebaseAuth.AuthStateListener() {
                @Override
                public void onAuthStateChanged(@NonNull FirebaseAuth firebaseAuth) {
                    FirebaseUser user = firebaseAuth.getCurrentUser();
                    if (user != null) {
                        // User is signed in to Firebase, but we can only get 
                        // basic info like name, email, and profile photo url
                        String name = user.getDisplayName();
                        String email = user.getEmail();
                        Uri photoUrl = user.getPhotoUrl();
    
                        // Even a user's provider-specific profile information
                        // only reveals basic information
                        for (UserInfo profile : user.getProviderData()) {
                            // Id of the provider (ex: google.com)
                            String providerId = profile.getProviderId();
                            // UID specific to the provider
                            String profileUid = profile.getUid();
                            // Name, email address, and profile photo Url
                            String profileDisplayName = profile.getDisplayName();
                            String profileEmail = profile.getEmail();
                            Uri profilePhotoUrl = profile.getPhotoUrl();
                        }
                    } else {
                        // User is signed out of Firebase
                    }
                }
            };
    
            // Google sign-in button listener
            findViewById(R.id.google_sign_in_button).setOnClickListener(this);
    
            // Configure GoogleSignInOptions
            GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
                    .requestIdToken(getString(R.string.server_client_id))
                    .requestServerAuthCode(getString(R.string.server_client_id))
                    .requestEmail()
                    .requestScopes(new Scope(PeopleScopes.USERINFO_PROFILE))
                    .build();
    
            // Build a GoogleApiClient with access to the Google Sign-In API and the
            // options specified by gso.
            mGoogleApiClient = new GoogleApiClient.Builder(this)
                    .enableAutoManage(this, this)
                    .addOnConnectionFailedListener(this)
                    .addConnectionCallbacks(this)
                    .addApi(Auth.GOOGLE_SIGN_IN_API, gso)
                    .build();
        }
    
        @Override
        public void onClick(View v) {
            switch (v.getId()) {
                case R.id.google_sign_in_button:
                    signIn();
                    break;
            }
        }
    
        private void signIn() {
            Intent signInIntent = Auth.GoogleSignInApi.getSignInIntent(mGoogleApiClient);
            startActivityForResult(signInIntent, RC_SIGN_IN);
        }
    
        @Override
        public void onActivityResult(int requestCode, int resultCode, Intent data) {
            super.onActivityResult(requestCode, resultCode, data);
    
            // Result returned from launching the Intent from GoogleSignInApi.getSignInIntent(...);
            if (requestCode == RC_SIGN_IN) {
                GoogleSignInResult result = Auth.GoogleSignInApi.getSignInResultFromIntent(data);
                if (result.isSuccess()) {
                    // Signed in successfully
                    GoogleSignInAccount acct = result.getSignInAccount();
    
                    // execute AsyncTask to get gender from Google People API
                    new GetGendersTask().execute(acct);
    
                    // Google Sign In was successful, authenticate with Firebase
                    firebaseAuthWithGoogle(acct);
                }
            }
        }
    
        class GetGendersTask extends AsyncTask<GoogleSignInAccount, Void, List<Gender>> {
            @Override
            protected List<Gender> doInBackground(GoogleSignInAccount... googleSignInAccounts) {
                List<Gender> genderList = new ArrayList<>();
                try {
                    HttpTransport httpTransport = new NetHttpTransport();
                    JacksonFactory jsonFactory = JacksonFactory.getDefaultInstance();
    
                    //Redirect URL for web based applications.
                    // Can be empty too.
                    String redirectUrl = "urn:ietf:wg:oauth:2.0:oob";
    
                    // Exchange auth code for access token
                    GoogleTokenResponse tokenResponse = new GoogleAuthorizationCodeTokenRequest(
                            httpTransport,
                            jsonFactory,
                            getApplicationContext().getString(R.string.server_client_id),
                            getApplicationContext().getString(R.string.server_client_secret),
                            googleSignInAccounts[0].getServerAuthCode(),
                            redirectUrl
                    ).execute();
    
                    GoogleCredential credential = new GoogleCredential.Builder()
                            .setClientSecrets(
                                getApplicationContext().getString(R.string.server_client_id), 
                                getApplicationContext().getString(R.string.server_client_secret)
                            )
                            .setTransport(httpTransport)
                            .setJsonFactory(jsonFactory)
                            .build();
    
                    credential.setFromTokenResponse(tokenResponse);
    
                    People peopleService = new People.Builder(httpTransport, jsonFactory, credential)
                            .setApplicationName("My Application Name")
                            .build();
    
                    // Get the user's profile
                    Person profile = peopleService.people().get("people/me").execute();
                    genderList.addAll(profile.getGenders());
                }
                catch (IOException e) {
                    e.printStackTrace();
                }
                return genderList;
            }
    
            @Override
            protected void onPostExecute(List<Gender> genders) {
                super.onPostExecute(genders);
                // iterate through the list of Genders to
                // get the gender value (male, female, other)
                for (Gender gender : genders) {
                    String genderValue = gender.getValue();
                }
            }
        }
    }
    

    You can find more information on Accessing Google APIs

    Login or Signup to reply.
  3. For Facebook :

    To get facebook accessToken from firebase is very simple. I was using firebase auth UI. After authentication with facebook you will get basic information from firebase user object like display name, email,provider details. But if you want more information like gender, birthday facebook Graph API is the solution. Once user authenticated with the facebook you can get access token like this.

    AccessToken.getCurrentAccessToken()
    But sometimes it will give you NULL value instead of valid access token. Make sure that you have initialized facebook SDK before that.

    public class MyApplication extends Application {
      @Override
      public void onCreate() {
         super.onCreate();
         FacebookSdk.sdkInitialize(this);
      }
    

    }
    After initialization use graphAPI

    if(AccessToken.getCurrentAccessToken()!=null) {
    
        System.out.println(AccessToken.getCurrentAccessToken().getToken());
    
        GraphRequest request = GraphRequest.newMeRequest(
                AccessToken.getCurrentAccessToken(),
                new GraphRequest.GraphJSONObjectCallback() {
                    @Override
                    public void onCompleted(JSONObject object, GraphResponse response) {
                        // Application code
                        try {
                            String email = object.getString("email");
                            String gender = object.getString("gender");
                        } catch (JSONException e) {
                            e.printStackTrace();
                        }
                    }
                });
        Bundle parameters = new Bundle();
        parameters.putString("fields", "id,name,email,gender,birthday");
        request.setParameters(parameters);
        request.executeAsync();
    
    }
    else
    {
        System.out.println("Access Token NULL");
    }
    

    Happy Coding 🙂

    Login or Signup to reply.
  4. Instead of using Googles People API classes to access their REST service I find it much simpler to just access the service directly.

    Also saves 1.5 MB of APK size.

      public static final String USER_BIRTHDAY_READ = "https://www.googleapis.com/auth/user.birthday.read";
      public static final String USER_PHONENUMBERS_READ = "https://www.googleapis.com/auth/user.phonenumbers.read";
      public static final String USERINFO_EMAIL = "https://www.googleapis.com/auth/userinfo.email";
      public static final String USERINFO_PROFILE = "https://www.googleapis.com/auth/userinfo.profile";
    
      public JSONObject getUserinfo(@NotNull Context context, @NotNull GoogleSignInAccount acct) {
    
        try {
          String token = GoogleAuthUtil.getToken(context, acct.getAccount(), "oauth2: " +USERINFO_PROFILE+" "+USER_PHONENUMBERS_READ+" "+USERINFO_EMAIL+" "+USER_BIRTHDAY_READ);
    
          URL url = new URL("https://people.googleapis.com/v1/people/me?"
                  +"personFields=genders,birthdays,phoneNumbers,emailAddresses"
                  +"&access_token=" + token);
          HttpURLConnection con = (HttpURLConnection) url.openConnection();
          int sc = con.getResponseCode();
          if (sc == 200) {
            InputStream is = con.getInputStream();
            JSONObject profile = new JSONObject(readStream(is));
            Log.d(TAG, "Got:" + profile.toString(2));
            Log.d(TAG, "genders: "+profile.opt("genders"));
            Log.d(TAG, "birthdays: "+profile.opt("birthdays"));
            Log.d(TAG, "phoneNumbers: "+profile.opt("phoneNumbers"));
            return profile;
          } else if (sc == 401) {
            GoogleAuthUtil.clearToken(context, token);
            Log.d("Server auth fejl, prøv igenn" + readStream(con.getErrorStream()));
          } else {
            Log.d("Serverfejl: " + sc);
          }
      } catch (UserRecoverableAuthException recoverableException) {
        startActivityForResult(recoverableException.getIntent(), 1234);
      } catch (Exception e) {
        e.printStackTrace();
      }
    
      public static String readStream(InputStream is) throws IOException {
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        byte[] data = new byte[2048];
        int len = 0;
        while ((len = is.read(data, 0, data.length)) >= 0) {
          bos.write(data, 0, len);
        }
        is.close();
        return new String(bos.toByteArray(), "UTF-8");
      }
    

    Output is easily parsable as JSON:

    genders: [{"metadata":{"primary":true,"source":{"type":"PROFILE","id":"101628018970026223117"}},"value":"male","formattedValue":"Male"}]
    birthdays:  [{"metadata":{"primary":true,"source":{"type":"PROFILE","id":"101628018970026223117"}},"date":{"year":1985,"month":3,"day":5}},{"metadata":{"source":{"type":"ACCOUNT","id":"101628018970026223117"}},"date":{"year":1985,"month":3,"day":5}}]
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search