When my Android app is running idle (i.e. doing nothing). The allocated memory slowly increases until there is no more 'Free' memory and when it hits the ceiling, the memory gets garbage collected I think.
Please look at the Image below.
MainActivity.class
public class MainActivity extends AppCompatActivity {
private final String TAG = "MainActivity";
// FIREBASE
private FirebaseAuth firebaseAuth;
private FirebaseAuth.AuthStateListener firebaseAuthListener;
// FACEBOOK
private CallbackManager FBcallbackManager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Initialize Firebase
firebaseAuth = FirebaseAuth.getInstance();
// Initialize Facebook Login button
FBcallbackManager = CallbackManager.Factory.create();
LoginButton loginButton = (LoginButton) findViewById(R.id.facebookButton);
loginButton.setReadPermissions("email", "public_profile");
loginButton.registerCallback(FBcallbackManager, new FacebookCallback<LoginResult>() {
#Override
public void onSuccess(LoginResult loginResult) {
handleFacebookAccessToken(loginResult.getAccessToken());
}
#Override
public void onCancel() {
}
#Override
public void onError(FacebookException error) {
}
});
final Intent intent = new Intent(MainActivity.this, NavigationActivity.class);
firebaseAuthListener = new FirebaseAuth.AuthStateListener() {
#Override
public void onAuthStateChanged(#NonNull FirebaseAuth firebaseAuth) {
FirebaseUser user = firebaseAuth.getCurrentUser();
if (user != null) {
Log.d(TAG, user.getDisplayName());
// User is signed in
// if so start next activty and close this one
Log.d(TAG, "User is logged in");
startActivity(intent);
finish();
} else {
// User is signed out
Log.d(TAG, "User is logged out");
}
}
};
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
FBcallbackManager.onActivityResult(requestCode, resultCode, data);
}
#Override
protected void onStart() {
super.onStart();
firebaseAuth.addAuthStateListener(firebaseAuthListener);
}
#Override
protected void onStop() {
super.onStop();
if (firebaseAuthListener != null) {
firebaseAuth.removeAuthStateListener(firebaseAuthListener);
}
}
private void handleFacebookAccessToken(AccessToken accessToken) {
final AuthCredential authCredential = FacebookAuthProvider.getCredential(accessToken.getToken());
firebaseAuth.signInWithCredential(authCredential).addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull Task<AuthResult> task) {
if (task.isSuccessful()) {
Log.d(TAG, "Authentication successful");
} else {
Log.d(TAG, "Authentication not successful");
Log.d(TAG, task.getException().getMessage());
}
}
});
}
}
hprof
MAT give me these problems:
Problem Suspect 1
74.846 instances of "java.lang.String", loaded by "" occupy 6.777.960 (29,27%) bytes.
Problem Suspect 2
33 instances of "java.lang.DexCache", loaded by "" occupy 5.293.808 (22,86%) bytes.
Problem Suspect 3
19 instances of "long[]", loaded by "" occupy 3.970.432 (17,15%) bytes.
Problem Suspect 4
5.082 instances of "java.lang.Class", loaded by "" occupy 2.811.328 (12,14%) bytes.
No, that is not normal. Sounds like you're creating new objects all the time.
Related
i'm a beginner who is learning how to use Android studio and this is my first time posting on Stack Overflow. I wish to implement Facebook login on my android app. I mostly followed this tutorial (https://www.youtube.com/watch?v=ImbuK35vmzs&t=1540s) to create the sign in using facebook.
While I'm able to run the app, ,whenever i click on the sign in using facebook button, the chrome browser opens up and the screen is stuck loading the facebook sign in page (refer to the screenshot). No error pops up on logcat, i've already enabled internet permission in the android manifest file as well as check to see the facebook access id + secret key were correctly copied. Below is my MainActivity.java code. Any idea why this issue might be happening and how do i go about troubleshooting it? Thank you.
Facebook Login Stuck:
public class MainActivity extends AppCompatActivity {
private FirebaseAuth mFirebaseAuth;
private CallbackManager mCallbackManager;
private TextView textViewUser;
private LoginButton loginButton;
private ImageView mLogo;
private FirebaseAuth.AuthStateListener authStateListener;
private AccessTokenTracker accessTokenTracker;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
FirebaseDatabase database = FirebaseDatabase.getInstance();
DatabaseReference myRef = database.getReference("message");
Button registerButton = findViewById(R.id.signupButton);
textViewUser = findViewById(R.id.textView_user);
mFirebaseAuth = FirebaseAuth.getInstance();
//Initialise facebook SDK
FacebookSdk.sdkInitialize(getApplicationContext());
//Assign textviewuser to the facebook button
mLogo = findViewById(R.id.image_logo);
loginButton = findViewById(R.id.facebook_button);
// Requesting read permission for the email and profile for facebook login
loginButton.setReadPermissions("email","public_profile");
mCallbackManager = CallbackManager.Factory.create();
loginButton.registerCallback(mCallbackManager, new FacebookCallback<LoginResult>() {
#Override
public void onSuccess(LoginResult loginResult) {
Log.d(TAG, "onSuccess" + loginResult);
handleFacebookToken(loginResult.getAccessToken());
}
#Override
public void onCancel() {
Log.d(TAG, "onCancel");
}
#Override
public void onError(#NonNull FacebookException error) {
Log.d(TAG, "onError" + error);
}
});
authStateListener = new FirebaseAuth.AuthStateListener(){
#Override
public void onAuthStateChanged(#NonNull FirebaseAuth firebaseAuth) {
FirebaseUser user = firebaseAuth.getCurrentUser();
if (user != null) {
updateUI(user);
} else {
updateUI(null);
}
}
};
accessTokenTracker = new AccessTokenTracker() {
#Override
protected void onCurrentAccessTokenChanged(AccessToken oldAccessToken, AccessToken currentAccessToken) {
if(currentAccessToken == null){
mFirebaseAuth.signOut();
}
}
};
private void handleFacebookToken(AccessToken token) {
Log.d(TAG, "handleFacebookToken" + token);
AuthCredential credential = FacebookAuthProvider.getCredential(token.getToken());
mFirebaseAuth.signInWithCredential(credential).addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull Task<AuthResult> task) {
if(task.isSuccessful()){
Log.d(TAG, "sign in with credential: successful");
FirebaseUser user = mFirebaseAuth.getCurrentUser();
updateUI(user);
}else{
Log.d(TAG, "sign in with credential: failure", task.getException());
Toast.makeText(MainActivity.this, "Authentication Failed", Toast.LENGTH_SHORT).show();
updateUI(null);
}
}
});
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data){
mCallbackManager.onActivityResult(requestCode, resultCode, data);
super.onActivityResult(requestCode, resultCode, data);
}
private void updateUI(FirebaseUser user) {
if (user != null) {
textViewUser.setText(user.getDisplayName());
if(user.getPhotoUrl()!=null){
String photoUrl= user.getPhotoUrl().toString();
photoUrl = photoUrl + "?type=large";
Picasso.get().load(photoUrl).into(mLogo);
}
}
else{
textViewUser.setText("");
mLogo.setImageResource((R.drawable.logo));
}
}
public void toastMsg(String message){
Toast.makeText(this,message,Toast.LENGTH_SHORT).show();
}
#Override
protected void onStart(){
super.onStart();
mFirebaseAuth.addAuthStateListener((authStateListener));
}
#Override
protected void onStop(){
super.onStop();
if(authStateListener!=null){
mFirebaseAuth.removeAuthStateListener(authStateListener);
}
}
}
Whenever i verify phone number with OTP then it should go to Register Layout but it returns to login layout. But when i close the app and run it again then it directly jumps to register layout.
I had check the code several times but not able to find the error.
here is the sample video: https://www.youtube.com/watch?v=elfg7bS3Cig
Here is my code
public class SplashScreenActivity extends AppCompatActivity {
private final static int LOGIN_REQUEST_CODE = 6262; //Any number you want
private List<AuthUI.IdpConfig> providers;
private FirebaseAuth firebaseAuth;
private FirebaseAuth.AuthStateListener listener;
private Uri filePath;
private ImageView img_drive_proof;
private final int PICK_IMAGE_REQUEST = 22;
#BindView(R.id.progress_bar)
ProgressBar progress_bar;
FirebaseDatabase database;
DatabaseReference driverInfoRef;
#Override
protected void onStart() {
super.onStart();
delaySplashScreen();
}
private void delaySplashScreen() {
progress_bar.setVisibility(View.VISIBLE);
Completable.timer(3, TimeUnit.SECONDS,
AndroidSchedulers.mainThread())
.subscribe(() ->
//After show Splash Screen, ask login if not login
firebaseAuth.addAuthStateListener(listener)
);
}
#Override
protected void onStop() {
if (firebaseAuth != null && listener != null)
firebaseAuth.addAuthStateListener(listener);
super.onStop();
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_splash_screen);
init();
}
private void init() {
ButterKnife.bind(this);
database = FirebaseDatabase.getInstance();
driverInfoRef = database.getReference(Common.DRIVER_INFO_REFERENCE);
providers = Arrays.asList(
new AuthUI.IdpConfig.PhoneBuilder().build(),
new AuthUI.IdpConfig.GoogleBuilder().build()
);
firebaseAuth = FirebaseAuth.getInstance();
listener = myFirebaseAuth -> {
FirebaseUser user = myFirebaseAuth.getCurrentUser();
if (user != null)
{
//Update Token
FirebaseInstanceId.getInstance()
.getInstanceId()
.addOnFailureListener(e -> Toast.makeText(SplashScreenActivity.this, "", Toast.LENGTH_SHORT).show())
.addOnSuccessListener(instanceIdResult -> {
Log.d("TOKEN",instanceIdResult.getToken());
UserUtils.updateToken(SplashScreenActivity.this, instanceIdResult.getToken());
});
checkUserFromFirebase();
}
else {
showLoginLayout();
}
};
}
private void showLoginLayout() {
AuthMethodPickerLayout authMethodPickerLayout = new AuthMethodPickerLayout
.Builder(R.layout.layout_sign_in)
.setPhoneButtonId(R.id.btn_phone_sign_in)
.setGoogleButtonId(R.id.btn_google_sign_in)
.build();
startActivityForResult(AuthUI.getInstance()
.createSignInIntentBuilder()
.setAuthMethodPickerLayout(authMethodPickerLayout)
.setIsSmartLockEnabled(false)
.setTheme(R.style.LoginTheme)
.setAvailableProviders(providers)
.build(),LOGIN_REQUEST_CODE);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, #Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if(requestCode == LOGIN_REQUEST_CODE)
{
IdpResponse response = IdpResponse.fromResultIntent(data);
if(resultCode == RESULT_OK)
{
FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
}
else
{
Toast.makeText(this, response.getError().getMessage(), Toast.LENGTH_SHORT).show();
}
}
}
private void checkUserFromFirebase() {
driverInfoRef.child(FirebaseAuth.getInstance().getCurrentUser().getUid())
.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
if (dataSnapshot.exists())
{
DriverInfoModel driverInfoModel = dataSnapshot.getValue(DriverInfoModel.class);
goToHomeActivity(driverInfoModel);
}
else
{
showRegisterLayout();
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
Toast.makeText(SplashScreenActivity.this, databaseError.getMessage(), Toast.LENGTH_SHORT).show();
}
});
}
private void showRegisterLayout() {
AlertDialog.Builder builder = new AlertDialog.Builder(this,R.style.DialogTheme);
View itemView = LayoutInflater.from(this).inflate(R.layout.layout_register,null);
TextInputEditText edt_first_name = (TextInputEditText)itemView.findViewById(R.id.edt_first_name);
TextInputEditText edt_last_name = (TextInputEditText)itemView.findViewById(R.id.edt_last_name);
TextInputEditText edt_phone = (TextInputEditText)itemView.findViewById(R.id.edt_phone_number);
img_drive_proof = (ImageView)itemView.findViewById(R.id.img_drive_proof);
Button btnUpload = (Button) itemView.findViewById(R.id.btnUpload);
Button btn_continue = (Button)itemView.findViewById(R.id.btn_register);
img_drive_proof.setOnClickListener(v -> SelectImage());
btnUpload.setOnClickListener(v -> uploadImage());
//Set data
if (FirebaseAuth.getInstance().getCurrentUser().getPhoneNumber() != null &&
!TextUtils.isEmpty(FirebaseAuth.getInstance().getCurrentUser().getPhoneNumber()))
edt_phone.setText(FirebaseAuth.getInstance().getCurrentUser().getPhoneNumber());
//Set View
builder.setView(itemView);
AlertDialog dialog = builder.create();
dialog.show();
btn_continue.setOnClickListener(v -> {
if (TextUtils.isEmpty(edt_first_name.getText().toString()))
{
Toast.makeText(this, "Please enter first name", Toast.LENGTH_SHORT).show();
return;
}
else if (TextUtils.isEmpty(edt_last_name.getText().toString()))
{
Toast.makeText(this, "Please enter last name", Toast.LENGTH_SHORT).show();
return;
}
else if (TextUtils.isEmpty(edt_phone.getText().toString()))
{
Toast.makeText(this, "Please enter phone number", Toast.LENGTH_SHORT).show();
return;
}
else
{
DriverInfoModel model = new DriverInfoModel();
model.setFirstName(edt_first_name.getText().toString());
model.setLastName(edt_last_name.getText().toString());
model.setPhoneNumber(edt_phone.getText().toString());
model.setRating(0.0);
driverInfoRef.child(FirebaseAuth.getInstance().getCurrentUser().getUid())
.setValue(model)
.addOnFailureListener(e ->
{
dialog.dismiss();
Toast.makeText(SplashScreenActivity.this, e.getMessage(), Toast.LENGTH_SHORT).show();
}
)
.addOnSuccessListener(aVoid -> {
Toast.makeText(this, "Register Successfully ", Toast.LENGTH_SHORT).show();
dialog.dismiss();
goToHomeActivity(model);
});
}
});
}
private void goToHomeActivity(DriverInfoModel driverInfoModel) {
Common.currentUser = driverInfoModel;
startActivity(new Intent(this,DriverHomeActivity.class));
finish();
}
}
you are probably not clearing your previous activity by providing a flag while firing the intent. pass clear top flag here:
startActivity(new Intent(this,DriverHomeActivity.class));
I have this mistake when I log in with Google
com.google.firebase.database.DatabaseException: Failed to get FirebaseDatabase instance: Specify DatabaseURL within FirebaseApp or from your getInstance() call.
at com.google.firebase.database.FirebaseDatabase.getInstance(com.google.firebase:firebase-database##16.0.5:114)
at com.google.firebase.database.FirebaseDatabase.getInstance(com.google.firebase:firebase-database##16.0.5:71)
at pl.cyfrogen.budget.ui.signin.SignInActivity.updateUI(SignInActivity.java:145)
at pl.cyfrogen.budget.ui.signin.SignInActivity.access$400(SignInActivity.java:41)
at pl.cyfrogen.budget.ui.signin.SignInActivity$3.onComplete(SignInActivity.java:130)
at com.google.android.gms.tasks.zzj.run(Unknown Source:4)
at android.os.Handler.handleCallback(Handler.java:883)
at android.os.Handler.dispatchMessage(Handler.java:100)
at android.os.Looper.loop(Looper.java:237)
at android.app.ActivityThread.main(ActivityThread.java:8167)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:496)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1100)
enter image description here
public class SignInActivity extends AppCompatActivity {
private static final int RC_SIGN_IN = 123;
private FirebaseAuth mAuth;
private GoogleSignInClient mGoogleSignInClient;
private TextView errorTextView;
private SignInButton signInButton;
private View progressView;
private TextView privacyPolicyTextView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_signin);
progressView = findViewById(R.id.progress_view);
mAuth = FirebaseAuth.getInstance();
GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
.requestIdToken(getString(R.string.default_web_client_id))
.requestEmail()
.build();
mGoogleSignInClient = GoogleSignIn.getClient(this, gso);
signInButton = findViewById(R.id.sign_in_button);
signInButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
signIn();
signInButton.setEnabled(false);
errorTextView.setText("");
}
});
privacyPolicyTextView = findViewById(R.id.privacy_policy_text_view);
SpannableStringBuilder spanTxt = new SpannableStringBuilder(
"By signing in, you are indicating that you have read and agree to the ");
spanTxt.append("privacy policy");
spanTxt.setSpan(new ClickableSpan() {
#Override
public void onClick(#NonNull View widget) {
Intent browserIntent = new Intent(Intent.ACTION_VIEW,
Uri.parse(Links.PRIVACY_POLICY_LINK));
startActivity(browserIntent);
}
}, spanTxt.length() - "privacy policy".length(), spanTxt.length(), 0);
privacyPolicyTextView.setMovementMethod(LinkMovementMethod.getInstance());
privacyPolicyTextView.setText(spanTxt, TextView.BufferType.SPANNABLE);
errorTextView = findViewById(R.id.error_textview);
}
#Override
public void onStart() {
super.onStart();
showProgressView();
FirebaseUser currentUser = mAuth.getCurrentUser();
updateUI(currentUser);
}
private void signIn() {
showProgressView();
Intent signInIntent = mGoogleSignInClient.getSignInIntent();
startActivityForResult(signInIntent, RC_SIGN_IN);
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == RC_SIGN_IN) {
Task<GoogleSignInAccount> task = GoogleSignIn.getSignedInAccountFromIntent(data);
try {
GoogleSignInAccount account = task.getResult(ApiException.class);
firebaseAuthWithGoogle(account);
} catch (ApiException e) {
e.printStackTrace();
hideProgressView();
loginError("Google sign in failed.");
}
}
}
private void firebaseAuthWithGoogle(GoogleSignInAccount acct) {
AuthCredential credential = GoogleAuthProvider.getCredential(acct.getIdToken(), null);
mAuth.signInWithCredential(credential)
.addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull Task<AuthResult> task) {
if (task.isSuccessful()) {
FirebaseUser user = mAuth.getCurrentUser();
updateUI(user);
} else {
loginError("Firebase auth failed.");
hideProgressView();
}
}
});
}
private void updateUI(FirebaseUser currentUser) {
if (currentUser == null) {
progressView.setVisibility(View.GONE);
return;
}
showProgressView();
final DatabaseReference userReference = FirebaseDatabase.getInstance().getReference("users").child(currentUser.getUid());
userReference.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
User user = dataSnapshot.getValue(User.class);
if (user != null) {
startActivity(new Intent(SignInActivity.this, MainActivity.class));
finish();
} else {
runTransaction(userReference);
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
loginError("Firebase fetch user data failed.");
hideProgressView();
}
});
}
private void loginError(String text) {
errorTextView.setText(text);
signInButton.setEnabled(true);
}
private void runTransaction(DatabaseReference userReference) {
showProgressView();
userReference.runTransaction(new Transaction.Handler() {
#Override
public Transaction.Result doTransaction(MutableData mutableData) {
User user = mutableData.getValue(User.class);
if (user == null) {
mutableData.setValue(new User());
return Transaction.success(mutableData);
}
return Transaction.success(mutableData);
}
#Override
public void onComplete(DatabaseError databaseError, boolean committed,
DataSnapshot dataSnapshot) {
if (committed) {
startActivity(new Intent(SignInActivity.this, MainActivity.class));
finish();
} else {
errorTextView.setText("Firebase create user transaction failed.");
hideProgressView();
}
}
});
}
private void showProgressView() {
progressView.setVisibility(View.VISIBLE);
}
private void hideProgressView() {
progressView.setVisibility(View.GONE);
}
#Override
public void onBackPressed() {
moveTaskToBack(true);
}
}
It looks like you're configuring Firebase without specifying the URL of the Realtime Database. There are a few reasons this could be happening:
If you are providing the configuration data in code, be sure to call setDatabaseUrl on your options.
This is especially likely when your database instance is hosted in another region than the (default) US one.
If you are providing the configuration data through the GoogleServices.json file, be sure to download a new version of that file after you create the database in the Firebase console.
This is a new requirement (since a few weeks ago) as the Realtime Database is now created on-demand (instead of auto-created when the project is created), so that you can pick in what region it's created.
Seems like you didn't connect your app to firebase.
You should:
connect your app to firebase
add Firebase Authentication to your project
You are also using Firebase Database. Connect it to your project.
After all, change this code
final DatabaseReference userReference = FirebaseDatabase.getInstance().getReference("users").child(currentUser.getUid());
to this:
final DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
final DatabaseReference userReference = rootRef.child("users").child(currentUser.getUid());
To conclude, as Frank mentioned, do not forget to download your google-services.json file and add it into the module (app-level) directory of your app
I'm new to android and now I'm working on making users to login using their facebook and gmail things going well but i need to know how do make the user to signout from the app and login in the user with new accounts. i tried a lot of tutorials but none of them are not as i thought and expected. The user when clicks on logout button from another activity and comebacks to login activity.
example: when user logins from UserAction.class the logout button is in ProfileFragment.class
I tried a lot but haven't found any solution any help.
Code i Tried
public class UserAction extends AppCompatActivity {
private CallbackManager callbackManager;
public LoginButton loginButton;
private static final String EMAIL = "email";
private SignInButton signInButton;
GoogleSignInClient mGoogleSignInClient;
private FirebaseAuth mAuth;
private int RC_SIGN_IN = 1;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_user_action);
this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
signInButton = findViewById(R.id.gmail_login_button);
mAuth = FirebaseAuth.getInstance();
GoogleSignInOptions gsp = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
.requestIdToken(getString(R.string.default_web_client_id))
.requestEmail()
.build();
mGoogleSignInClient = GoogleSignIn.getClient(this, gsp);
signInButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
GmailLogin();
}
private void GmailLogin() {
Intent mailSignIn = mGoogleSignInClient.getSignInIntent();
startActivityForResult(mailSignIn,RC_SIGN_IN);
}
});
AccessToken accessToken = AccessToken.getCurrentAccessToken();
boolean isLoggedIn = accessToken != null && !accessToken.isExpired();
AppEventsLogger.activateApp(getApplication());
callbackManager = CallbackManager.Factory.create();
loginButton = (LoginButton) findViewById(R.id.fb_login_button);
loginButton.setReadPermissions(Arrays.asList(EMAIL));
loginButton.registerCallback(callbackManager, new FacebookCallback<LoginResult>() {
#Override
public void onSuccess(LoginResult loginResult) {
Intent intent = new Intent(UserAction.this, AppMain.class);
startActivity(intent);
}
#Override
public void onCancel() {
// App code
}
#Override
public void onError(FacebookException exception) {
// App code
}
});
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
callbackManager.onActivityResult(requestCode, resultCode, data);
if (requestCode == RC_SIGN_IN){
Task<GoogleSignInAccount> task = GoogleSignIn.getSignedInAccountFromIntent(data);
handleSignInResult(task);
}
super.onActivityResult(requestCode, resultCode, data);
}
private void handleSignInResult(Task<GoogleSignInAccount> CompletedTask) {
try {
GoogleSignInAccount account = CompletedTask.getResult(ApiException.class);
Toast.makeText(this, "Signed in Successfully", Toast.LENGTH_SHORT).show();
FirebaseGoogleAuth(Objects.requireNonNull(account));
} catch (ApiException e) {
ConstraintLayout UserAction = findViewById(R.id.userAction);
Snackbar snackbar = Snackbar.make(UserAction,"Login Failed Please try Again.", Snackbar.LENGTH_SHORT);
snackbar.show();
FirebaseGoogleAuth(null);
}
}
private void FirebaseGoogleAuth(final GoogleSignInAccount account) {
AuthCredential authCredential = GoogleAuthProvider.getCredential(account.getIdToken(), null);
mAuth.signInWithCredential(authCredential).addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull Task<AuthResult> task) {
if (task.isSuccessful()){
FirebaseUser user = mAuth.getCurrentUser();
GoogleSignInAccount googleSignInAccount = GoogleSignIn.getLastSignedInAccount(getApplicationContext());
String personName = Objects.requireNonNull(googleSignInAccount).getDisplayName();
String personEmail = googleSignInAccount.getEmail();
String personId = googleSignInAccount.getId();
Toast.makeText(UserAction.this, personName+ "\n" +personEmail + "\n" + personId , Toast.LENGTH_SHORT).show();
}
}
});
}
}
To sign out from Firebase use
mAuth.signOut();
And to sign out from google client use
mGoogleSignInClient.signOut()
I am making an chat app and I want to do the following:
When starting the MainActivity, check if the user is logged in. If not, start FirebaseAuthUI.
But FirebaseAuth only supports a few parameters and, to add more, I created a Database node do each user, which store other parameters.
To get this parameters, after finishing FirebaseAuth, the user is redirected to an Activity that get all extra information and store in the user's node in the Database. All of this is working just fine.
But after the user fill the information in this Info Activity and finish the register, it should go back to MainActivity and stay there. How can I do that?
I am trying it this way:
I added to each user a Boolean variable called userCompleted, which informs if the user have already gave their information. I check if this variable is false, and if so, I call the Info Activity intent and, in the when the user press the button to complete the registration in this Activity, it sets the userCompleted value to true in the user node in the Database and then start an intent that leads to MainActivity.
The problem is that in the Database, userCompleted is set to true and then immediately goes back to false, and I don't know why. Also, I guess I am having trouble on reading userCompleted from the Database, probably because I haven't worked much with asynchronous tasks.
I used a variable isUserCompleted declared in Main Activity to get track of the userCompleted value.
A way to check if is the first time the user is logging in would be useful too, although it wouldn't solve my whole problem.
This is my current code:
(if need more to try to understand the problem just ask in the comments)
Create AuthStateListener
public void setAuthStateListener(){
mAuthStateListener = new FirebaseAuth.AuthStateListener() {
#Override
public void onAuthStateChanged(#NonNull FirebaseAuth firebaseAuth) {
FirebaseUser user = firebaseAuth.getCurrentUser();
if (user != null) {
onSignInInitialize(user);
Log.d(TAG, "userUid = " + user.getUid());
Toast.makeText(SearchActivity.this, "Signed in!", Toast.LENGTH_SHORT).show();
} else {
onSignOutCleanup();
startLoginUI();
}
}
};
}
onSignInInitialize()
public void onSignInInitialize(final FirebaseUser user){
mLoggedFBUser = user;
mUserReference = mUsersDatabaseReference.child(user.getUid());
mUserReference.child("uid").setValue(user.getUid());
mUserReference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
User user = dataSnapshot.getValue(User.class);
isUserCompleted = user.isUserCompleted();
Log.d(TAG, "UserCompleted (onDataChanged) "+ isUserCompleted);
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
Log.d(TAG, "UserCompleted (Before startActivity if) "+ isUserCompleted);
if (!isUserCompleted) {
startCreateProfileActivity(user);
}
Log.d(TAG, "UserCompleted (After startActivity if) "+ isUserCompleted);
mUserReference.child("username").setValue(user.getDisplayName());
mUserReference.child("email").setValue(user.getEmail());
attachChildEventListener();
}
Go back to Main Activity
mFinishButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
mUserDatabaseReference.child("userCompleted").setValue(true);
Intent intent = new Intent (CreateVolunteerProfile.this, SearchActivity.class);
startActivity(intent);
}
});
Entire MainActivity block (Actually it's called SearchActivity)
public class SearchActivity extends AppCompatActivity implements RecyclerAdapter.UserItemClickListener {
private RecyclerView recyclerView;
private RecyclerView.Adapter adapter;
private RecyclerView.LayoutManager layoutManager;
private ArrayList<User> users = new ArrayList<User>();
private String mLoggedUserId = "user2";
private String mLoggedUsername;
private User mLoggedUser;
private FirebaseUser mLoggedFBUser;
//private boolean isUserCompleted;
private SharedPreferences mSharedPreferences;
private SharedPreferences.Editor mPreferencesEditor;
private boolean firstTime = true;
private static final String TAG = "Search Activity";
private static final int USER_CLICK = 1;
private static final int RC_SIGN_IN = 1;
private static final int RC_CREATE_PROFILE = 2;
//Firebase
private FirebaseDatabase mFirebaseDatabase;
private DatabaseReference mUsersDatabaseReference;
private DatabaseReference mUserReference;
private ChildEventListener mChildEventListener;
private FirebaseAuth mFirebaseAuth;
private FirebaseAuth.AuthStateListener mAuthStateListener;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_search);
View loadingView = findViewById(R.id.cl_loading);
loadingView.setVisibility(View.VISIBLE);
//RecyclerView
recyclerView = findViewById(R.id.rv_users);
recyclerView.setHasFixedSize(true);
layoutManager = new LinearLayoutManager(this);
recyclerView.setLayoutManager(layoutManager);
adapter = new RecyclerAdapter(users, this);
recyclerView.setAdapter(adapter);
//Firebase
mFirebaseDatabase = FirebaseDatabase.getInstance();
mFirebaseAuth = FirebaseAuth.getInstance();
mUsersDatabaseReference = mFirebaseDatabase.getReference().child("users");
setAuthStateListener();
loadingView.setVisibility(View.GONE);
}
#Override
protected void onResume() {
super.onResume();
mFirebaseAuth.addAuthStateListener(mAuthStateListener);
}
#Override
protected void onPause() {
super.onPause();
if (mAuthStateListener != null)
mFirebaseAuth.removeAuthStateListener(mAuthStateListener);
detachChildEventListener();
clearAdapter();
}
#Override
protected void onSaveInstanceState(Bundle outState) {
Log.wtf(TAG, "onSaveInstanceState userId = "+ mLoggedUserId);
//Log.wtf(TAG, "UserCompleted (onSaveInstanceState) " + isUserCompleted);
outState.putString("userId", mLoggedUserId);
//outState.putBoolean("isUserCompleted", isUserCompleted);
super.onSaveInstanceState(outState);
}
#Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
mLoggedUserId = savedInstanceState.getString("userId");
//isUserCompleted = savedInstanceState.getBoolean("isUserCompleted");
//Log.wtf(TAG, "UserCompleted (onRestoreInstanceState) " + isUserCompleted);
Log.wtf(TAG, "onRestoreInstanceState userId = "+ mLoggedUserId);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, #Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if((requestCode == RC_SIGN_IN) && firstTime){
if (resultCode == RESULT_OK){
//Toast.makeText(this, "Signed in!", Toast.LENGTH_SHORT).show();
} else if (resultCode == RESULT_CANCELED){
Toast.makeText(this, "Sign in canceled!", Toast.LENGTH_SHORT).show();
finish();
}
}
if((requestCode == RC_CREATE_PROFILE)){
if (resultCode == RESULT_OK){
//isUserCompleted = true;
}
}
}
#Override
public void onUserItemClick(int clickedUserIndex) {
Intent intent = new Intent (this, ChatActivity.class);
FirebaseUser user = mFirebaseAuth.getCurrentUser();
if(user != null) {
mLoggedUserId = user.getUid();
intent.putExtra("user1", mLoggedUserId);
String mUserRecieverId = users.get(clickedUserIndex).getUid();
intent.putExtra("user2", mUserRecieverId);
Log.wtf(TAG, "SearchActivity // user = " + users.get(clickedUserIndex));
Log.wtf("1", "SearchActivity // mLoggedUserId = " + mLoggedUserId + " // users.getUid() = " + users.get(clickedUserIndex).getUid());
startActivityForResult(intent, USER_CLICK);
}
else {
Toast.makeText(this, "ERROR", Toast.LENGTH_SHORT).show();
}
}
public void setAuthStateListener(){
mAuthStateListener = new FirebaseAuth.AuthStateListener() {
#Override
public void onAuthStateChanged(#NonNull FirebaseAuth firebaseAuth) {
FirebaseUser user = firebaseAuth.getCurrentUser();
if (user != null) {
mUserReference = mUsersDatabaseReference.child(user.getUid());
onSignInInitialize(user);
Log.wtf(TAG, "userUid = " + user.getUid());
Toast.makeText(SearchActivity.this, "Signed in!", Toast.LENGTH_SHORT).show();
} else {
onSignOutCleanup();
startLoginUI();
}
}
};
}
public void onSignInInitialize(final FirebaseUser user){
mLoggedFBUser = user;
mUserReference = mUsersDatabaseReference.child(user.getUid());
mUserReference.child("uid").setValue(user.getUid());
boolean isUserCompleted = false;
mUserReference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
User user = dataSnapshot.getValue(User.class);
isUserCompleted = user.isUserCompleted();
Log.wtf(TAG, "UserCompleted (onDataChanged) "+ isUserCompleted);
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
Log.wtf(TAG, "UserCompleted (Before startActivity if) "+ isUserCompleted);
if (!isUserCompleted) {
startCreateProfileActivity(user);
}
Log.wtf(TAG, "UserCompleted (After startActivity if) "+ isUserCompleted);
mUserReference.child("username").setValue(user.getDisplayName());
mUserReference.child("email").setValue(user.getEmail());
attachChildEventListener();
}
public void onSignOutCleanup(){
mLoggedUser = null;
mLoggedUserId = null;
mLoggedUsername = null;
detachChildEventListener();
clearAdapter();
}
public void attachChildEventListener(){
if (mChildEventListener == null){
mChildEventListener = new ChildEventListener() {
#Override
public void onChildAdded(#NonNull DataSnapshot dataSnapshot, #Nullable String s) {
User user = dataSnapshot.getValue(User.class);
users.add(user);
Log.d(TAG, "onChildAdded userId = "+ user.getUid());
//adapter.notifyItemInserted(users.size()-1);
adapter.notifyDataSetChanged();
}
#Override
public void onChildChanged(#NonNull DataSnapshot dataSnapshot, #Nullable String s) { }
#Override
public void onChildRemoved(#NonNull DataSnapshot dataSnapshot) { }
#Override
public void onChildMoved(#NonNull DataSnapshot dataSnapshot, #Nullable String s) { }
#Override
public void onCancelled(#NonNull DatabaseError databaseError) { }
};
}
mUsersDatabaseReference.addChildEventListener(mChildEventListener);
}
public void detachChildEventListener(){
if (mChildEventListener != null){
mUsersDatabaseReference.removeEventListener(mChildEventListener);
mChildEventListener = null;
}
}
public void clearAdapter() {
final int size = users.size();
if (size > 0) {
for (int i = 0; i < size; i++) {
users.remove(0);
}
adapter.notifyItemRangeRemoved(0, size);
}
}
public void startCreateProfileActivity(FirebaseUser user){
mUsersDatabaseReference.child(user.getUid()).child("userCompleted").setValue(false);
Intent intent = new Intent(SearchActivity.this, CreateProfileActivity.class);
intent.putExtra("userId", user.getUid());
startActivityForResult(intent, RC_CREATE_PROFILE);
}
public void startLoginUI(){
startActivityForResult(
AuthUI.getInstance()
.createSignInIntentBuilder()
.setIsSmartLockEnabled(false)
.setLogo(R.mipmap.logo)
.setAvailableProviders(Arrays.asList(
new AuthUI.IdpConfig.GoogleBuilder().build(),
//new AuthUI.IdpConfig.FacebookBuilder().build(),
//new AuthUI.IdpConfig.TwitterBuilder().build(),
//new AuthUI.IdpConfig.GitHubBuilder().build(),
new AuthUI.IdpConfig.EmailBuilder().build()))
//new AuthUI.IdpConfig.PhoneBuilder().build(),
//new AuthUI.IdpConfig.AnonymousBuilder().build()))
.build(),
RC_SIGN_IN);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater menuInflater = getMenuInflater();
menuInflater.inflate(R.menu.search_menu, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()){
case R.id.sign_out_item:
AuthUI.getInstance().signOut(this);
return true;
default:
return super.onOptionsItemSelected(item);
}
}
}
I think the simplest way is if a user clicked on finish Btn successfully make a flag with true else make it false
in your MainActivity
firebase.auth().onAuthStateChanged(function(user) {
// User signed in and not registered
if (user&&!isPressedOnFinishBtn) {
// User is signed in.
}
user clicked on finish btn
else if(isPressedOnFinishBtn) {
// No user is signed in.
}
});
This is how you can do that .
Create a method inside your Login activity .
private void AllowUserToLogin() {
String userName = userEmail.getText().toString();
String userPass = userPassword.getText().toString();
if (TextUtils.isEmpty(userName) || TextUtils.isEmpty(userPass)) {
Toast.makeText(this, "Enter user Name / password first . . .", Toast.LENGTH_SHORT).show();
} else {
dialogBar.setTitle("Sign In ");
dialogBar.setMessage("Please Wait . . .");
dialogBar.setCanceledOnTouchOutside(true);
dialogBar.show();
mAuth.signInWithEmailAndPassword(userName, userPass)
.addOnCompleteListener(new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull Task<AuthResult> task) {
if (task.isSuccessful()) {
String currentUserID = mAuth.getCurrentUser().getUid();
String deviceToken = Settings.Secure.getString(getApplicationContext().getContentResolver(),
Settings.Secure.ANDROID_ID);
UsersRef.child(currentUserID).child("device_token")
.setValue(deviceToken)
.addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
if(task.isSuccessful()){
sendUserToMainActivity();
Toast.makeText(LoginPage.this, "Logged in Successfull . . . ", Toast.LENGTH_SHORT).show();
dialogBar.dismiss();
}
}
});
} else {
String error = task.getException().toString();
Toast.makeText(LoginPage.this, "Wrong Email or Password: " + error, Toast.LENGTH_SHORT).show();
dialogBar.dismiss();
}
}
});
}
}
and on ur onClick() method .
#Override
public void onClick(View v) {
if (v == needNewAccount) {
sendUserToRegisterActivity();
} else if (v == loginButton) {
AllowUserToLogin();
}else if(v == phone_button){
Intent phoneLoginIntent = new Intent(LoginPage.this , PhoneLoginActivity.class);
startActivity(phoneLoginIntent);
}
}
this is sendUserToRegisterActivity()
private void sendUserToRegisterActivity() {
Intent registerIntent = new Intent(LoginPage.this, RegisterationForm.class);
startActivity(registerIntent);
}
This is sendUserToMainActivity() .
private void sendUserToMainActivity() {
Intent mainIntent = new Intent(LoginPage.this, MainActivity.class);
mainIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(mainIntent);
finish();
}