0

I have two activities LoginActivity and MainActivity, I authenticate my user from the LoginActivity. If the user was authenticated successfully, I call startActivity() with the MainActivity intent. This is what the LoginActivity looks like:

In my onCreate() I initialised my SharedPreferences objects which had been declared as fields of the class:

 userInfo = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
 editor = userInfo.edit();

Then I handle authentication logic in the login() method:

private void login() {


    progressDialog.setIndeterminate(true);
    progressDialog.setMessage("Authenticating...");
    progressDialog.show();

    final String email = emailText.getText().toString();
    final String password = passwordText.getText().toString();


    new android.os.Handler().postDelayed(new Runnable() {

        public void run() {
            ref.authWithPassword(email, password, new Firebase.AuthResultHandler({      

            // User was authenticated successfully
            @Override
            public void onAuthenticated(AuthData authData) {

              @Override
              public void onDataChange(DataSnapshot snapshot) {
              UserSchema user = snapshot.getValue(UserSchema.class);

                // store the user's name and email with our SharedPreferences
                 editor.putString("name", user.getName());
                 editor.putString("email", user.getEmail());
                 editor.apply();
               }  
          });

         // Dismiss the progress dialog shown while authenticating the user
         progressDialog.dismiss();

      // Start the MainActivity
      Intent intent = new Intent(getApplicationContext(), MainActivity.class);
      startActivity(intent); 
      }
    }
      }, 3000);
   }

I am also initialising the PreferenceManager in the MainActivity's onCreate():

  userInfo = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());

Everything works fine at first but when the MainActivity starts, all calls to get the user's info that was stored returns with the default values I had set in the MainActivity class:

  // returns the default value at first
  String s1 = userInfo.getString("name", "name"); 
  String s2 = userInfo.getString("email", "email");

Weird part: If I close the app from my device's recents and relaunch it, the right values of the user's name and email show up correctly.

Feyisayo Sonubi
  • 1,052
  • 5
  • 15
  • 27
  • Please show a more complete example. All lines of code should be inside a method and all methods should be inside a class. – Code-Apprentice Feb 21 '16 at 18:07
  • Also, the code shown won't even compile. `onDataChange()` is declared inside `login()`. You cannot have a method within another method. – Code-Apprentice Feb 21 '16 at 18:08
  • @Code-Apprentice: Looks like `onDataChange()` is a part of interface which is implemented in `login()`. Just like a `onClickListener` inside a method. Just assuming because OP talks about login. Probably a network hit or something. – Rohit5k2 Feb 21 '16 at 18:23
  • @Rohit5k2 The syntax as shown here is incorrect; it will not compile. You cannot put a method inside another method. You are probably thinking of an anonymous inner class which is often used for `onClickListener()`. If that is what the OP is doing, a lot of code is missing. – Code-Apprentice Feb 21 '16 at 19:19
  • Yes, I think OP has remove some of the code block because `...` is there at the top of the method – Rohit5k2 Feb 21 '16 at 19:20
  • The `...` obviously indicates that you removed some code which you thought was irrelevant to the question. However, you have removed too much. In particular, you need to show the anonymous inner class which contains `onDataChange()` and the line where this class is used. – Code-Apprentice Feb 21 '16 at 19:22
  • @Code-Apprentice Ohh. I removed the rest of the code so I can go straight to the point, hence why I had `...` to indicate. I'll update the question now. – Feyisayo Sonubi Feb 21 '16 at 21:03

2 Answers2

3

Notice that onDataChange is a callback and it won't get called immediately, but startActivity gets called before this callback is hit. So, MainActivity is called before data gets saved to SharedPreference.

The code should be like this

private void login() {
    ...
    // User was authenticated successfully
    @Override
    public void onDataChange(DataSnapshot snapshot) {
        UserSchema user = snapshot.getValue(UserSchema.class);

        // store the user's name and email with our SharedPreferences
        editor.putString("name", user.getName());
        editor.putString("email", user.getEmail());
        editor.apply();

        // Start the MainActivity
        Intent intent = new Intent(getApplicationContext(), MainActivity.class);
        startActivity(intent);
    } 
}
Rohit5k2
  • 17,948
  • 8
  • 45
  • 57
1

I'm not sure but try using editor.commit(); instead of editor.apply(); because with commit it store the data immediately.

Boukharist
  • 1,219
  • 11
  • 19
  • 1
    I also didn't knew the difference between commit() and apply(). Found the difference here : http://stackoverflow.com/questions/5960678/whats-the-difference-between-commit-and-apply-in-shared-preference . I think issue is not in apply() but something else. – Alok Gupta Feb 21 '16 at 18:11