0

Hello I'm new to Android development. I am currently trying to build a basic android application with Google's Firebase as its backend system.

I have a "Login with Facebook" button, whenever this button is clicked it opens up a dialog where the user enters his facebook credentials in order to get access to the application. When that's done, I want to store his email, name and id in Firebase if it's his first time logging in, if it's not his first time logging in I want to update his information.

I made a class called User (POJO) that I will use to represent this data. My problem is that I don't seem to know where to put the code that stores this information. Here's my MainActivity class:

public class MainActivity extends AppCompatActivity {

    //Declare our view variables
    private LoginButton mLoginButton;
    private CallbackManager mCallbackManager;
    private FirebaseAuth mAuth;
    private FirebaseAuth.AuthStateListener mAuthListener;
    private FirebaseDatabase mDatabase;
    private DatabaseReference mDatabaseReference;

    private static final String TAG = "MainActivity";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        FacebookSdk.sdkInitialize(getApplicationContext());
        setContentView(R.layout.activity_main);

        //Initialize callback manager
        mCallbackManager = CallbackManager.Factory.create();

        //Assign the views to the corresponding variables
        mLoginButton = (LoginButton) findViewById(R.id.login_button);

        //Assign the button permissions
        mLoginButton.setReadPermissions("email", "public_profile");

        //Create instance of database
        mDatabase = FirebaseDatabase.getInstance();
        mDatabaseReference = mDatabase.getReference();

        //Assign the button a task
        mLoginButton.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);
            }
        });

        // Initialize Firebase Auth
        mAuth = FirebaseAuth.getInstance();

        mAuthListener = new FirebaseAuth.AuthStateListener() {
            @Override
            public void onAuthStateChanged(@NonNull FirebaseAuth firebaseAuth) {
                //Get currently logged in user
                FirebaseUser user = firebaseAuth.getCurrentUser();

                if (user != null) {
                    // User is signed in
                    Log.d(TAG, "onAuthStateChanged:signed_in:" + user.getUid());

                    // Name, email address
                    String name = user.getDisplayName();
                    String email = user.getEmail();

                    // 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();

                    //Create user
                    final User loggedIn = new User(uid, name, email);

                    mDatabaseReference.child("users").child(loggedIn.getId()).setValue(loggedIn);

                    mDatabaseReference.child("users").addValueEventListener(new ValueEventListener() {
                        @Override
                        public void onDataChange(DataSnapshot dataSnapshot) {
                            // This method is called once with the initial value and again
                            // whenever data at this location is updated.

                        }

                        @Override
                        public void onCancelled(DatabaseError error) {
                            // Failed to read value
                            Log.w(TAG, "Failed to read value.", error.toException());
                        }
                    });

                } else {
                    // User is signed out
                    Log.d(TAG, "onAuthStateChanged:signed_out");
                }
            }
        };
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        // Pass the activity result back to the Facebook SDK
        mCallbackManager.onActivityResult(requestCode, resultCode, data);
    }

    @Override
    public void onStart() {
        super.onStart();
        mAuth.addAuthStateListener(mAuthListener);
    }

    @Override
    public void onStop() {
        super.onStop();
        if (mAuthListener != null) {
            mAuth.removeAuthStateListener(mAuthListener);
        }
    }

    //If user successfully signs in the LoginButton's onSuccess callback method
    // get an access token for the signed-in user, exchange it for a Firebase credential
    // and authenticate with Firebase using the Firebase credential

    private void handleFacebookAccessToken(AccessToken token) {
        Log.d(TAG, "handleFacebookAccessToken:" + token);

        AuthCredential credential = FacebookAuthProvider.getCredential(token.getToken());
        mAuth.signInWithCredential(credential)
                .addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
                    @Override
                    public void onComplete(@NonNull Task<AuthResult> task) {
                        Log.d(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.w(TAG, "signInWithCredential", task.getException());
                            Toast.makeText(MainActivity.this, "Authentication failed.", Toast.LENGTH_SHORT).show();
                        }
                    }
                });
    }
}

Here's my User class:

public class User {
    private String id;
    private String name;
    private String email;

    public User(){

    }

    public User(String id, String name, String email) {
        this.id = id;
        this.name = name;
        this.email = email;
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

}

Thank you for your time

2
  • It looks like you have already put the code on your AuthStateChanged listener. Isn't that working for you? Commented Feb 16, 2017 at 8:45
  • @RosárioPereiraFernandes no, it isn't Commented Feb 16, 2017 at 15:56

2 Answers 2

1

You've already done the most work, so i am going to create two methods for you to use.

protected void getUserInfo(final LoginResult login_result){

    GraphRequest data_request = GraphRequest.newMeRequest(
            login_result.getAccessToken(),
            new GraphRequest.GraphJSONObjectCallback() {
                @Override
                public void onCompleted(
                        JSONObject object,
                        GraphResponse response) {
                    try {
                        String facebook_id = object.getString("id");
                        String f_name = object.getString("name");
                        String email_id = object.getString("email");
                        String token = login_result.getAccessToken().getToken();
                        String picUrl = "https://graph.facebook.com/me/picture?type=normal&method=GET&access_token="+ token;

saveFacebookCredentialsInFirebase(login_result.getAccessToken());

                    } catch (JSONException e) {
                        // TODO Auto-generated catch block
                    }
                }
            });
    Bundle permission_param = new Bundle();
    permission_param.putString("fields", "id,name,email,picture.width(120).height(120)");
    data_request.setParameters(permission_param);
    data_request.executeAsync();
    data_request.executeAsync();
}

This is where you save the data in firebase

private void saveFacebookCredentialsInFirebase(AccessToken accessToken){
  AuthCredential credential = FacebookAuthProvider.getCredential(accessToken.getToken());
    firebaseAuth.signInWithCredential(credential).addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
        @Override
        public void onComplete(@NonNull Task<AuthResult> task) {
            if(!task.isSuccessful()){
                Toast.makeText(getApplicationContext(),"Error logging in", Toast.LENGTH_LONG).show();
            }else{
               Toast.makeText(getApplicationContext(),"Login in Successful", Toast.LENGTH_LONG).show();  
            }
        }
    });    
}
Sign up to request clarification or add additional context in comments.

1 Comment

in this solution, how can i return the user information i collected in function getUserInfo ? the onCompleted is called after the return statement due to which i'm getting empty data
0

I downgraded firebase to 9.6.0 to avoid the Google Play Services errors and I saved the user after he signs in with his credentials in the handleFacebookAccessToken method.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.