I'm trying to implement Firebase with an Android application, and I've written a simple login code. The problem is that unless the Firebase code is used within the Activity class, the user is required to press the login button twice.
In short, the user tries to login, but the Firebase reference isn't retrieved instant, and so returns a false result. However, a few seconds later, you can see that LogCat returns a true result, and if the user then clicks the login button again, he/she's able to login.
LogCat
04-30 10:29:25.003: I/WMT(30932): activity
04-30 10:29:25.003: I/WMT(30932): controller
04-30 10:29:25.003: I/kolla(30932): https://REMOVEDURL.firebaseio.com/users/testing
04-30 10:29:25.003: I/kolla(30932): ITS TRUE!
04-30 10:29:25.133: D/dalvikvm(30932): GC_CONCURRENT freed 514K, 14% free 9799K/11271K, paused 6ms+13ms, total 62ms
04-30 10:29:26.274: I/kolla(30932): datachange
04-30 10:29:26.274: I/kolla(30932): https://REMOVEDURL.firebaseio.com/users/testing
04-30 10:29:26.274: I/kolla(30932): hej
04-30 10:29:26.274: I/kolla(30932): Normal password: hej
04-30 10:29:26.274: I/kolla(30932): Password is correct
04-30 10:29:26.274: I/kolla(30932): userExists is true
The calling activity
public class MainActivity extends Activity {
private MainController mainController;
private EditText edtUsername;
private EditText edtPassword;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mainController = new MainController();
edtUsername = (EditText)findViewById(R.id.edtUsername);
edtPassword = (EditText)findViewById(R.id.edtPassword);
}
public void btnLoginClick(View view)
{
Log.i("WMT", "activity");
if(mainController.login(edtUsername.getText().toString(), edtP assword.getText().toString()) != null) {
Toast toast = Toast.makeText(getApplicationContext(), "Login correct, redirecting...", Toast.LENGTH_LONG);
toast.show();
User user = mainController.login(edtUsername.getText().toString(), edtPassword.getText().toString());
Intent intent = new Intent(this, UserWindowActivity.class);
intent.putExtra("user", user);
startActivity(intent);
} else {
Toast toast = Toast.makeText(getApplicationContext(), "Invalid username and/or password", Toast.LENGTH_SHORT);
toast.show();
}
}
}
Controller
public final class MainController {
// This controller handles main activity
private FirebaseDba dba;
public MainController() {
dba = new FirebaseDba();
}
public User login(String username, String password) {
Log.i("WMT", "controller");
return dba.login(username, password);
}
}
Database access class
public class FirebaseDba {
private final String FIREBASE_URL = //Removed for safety purposes;
private Firebase fb;
// String savedPassword;
boolean userExists;
public FirebaseDba() {
fb = new Firebase(FIREBASE_URL);
}
private Firebase getFirebaseConnection() {
return fb;
}
public User login(final String username, final String password) {
final Firebase dbaa = new Firebase(fb.toString() + "/users/" + username);
Log.i("kolla", dbaa.toString());
dbaa.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot snap) {
Log.i("kolla" ,"datachange");
Log.i("kolla", dbaa.toString());
Object value = snap.getValue();
if (value != null) {
String dbPassword = snap.child("password").getValue().toString();
Log.i("kolla", dbPassword);
Log.i("kolla", "Normal password: " + password);
if (password.equals(dbPassword)) {
Log.i("kolla", "Password is correct");
changeToTrue();
if(userExists) Log.i("kolla", "userExists is true");
}
}
else {
userExists = false;
}
}
@Override
public void onCancelled(FirebaseError arg0) {
// TODO Auto-generated method stub
}
});
Log.i("kolla", "ITS TRUE!");
if (userExists == true) {
Log.i("kolla", "userExists equals true");
return new User(username, password);
}
//return new User(username, password);
return null;
}
public void changeToTrue() {
userExists = true;
}
}
EDIT: Aren't there anyone that has had this problem? Is everyone running their DB-access in their Activity? Cause that sounds like bad practice, and I'd like to solve this issue with a separate class. All help appreciated.