In the setUser method, I am trying to read data from my database which I will use to create an instance of User, Worker, Manager, or Administrator.I also know that the following three lines of code are incorrect, but they don't raise any errors, so they can be ignored for now.
String name = mUserDatabase.child(uniqueId).child("name").orderByValue().toString();
int zip = mUserDatabase.child(uniqueId).child("zipcode").orderByValue().hashCode();
String phone = mUserDatabase.child(uniqueId).child("phone number").orderByValue().toString();
What baffles me is that onDataChange is entered in onActivityResult but not in setUser. I cannot understand why onDataChange is not entered in setUser. The firebase reference is correct, and I navigated to the url logged with typ.toString() and it went to the correct entry. I also have set permissions to public, if that is relevant. I am also connected to the Internet. I also looked at other answers to similar questions which had answers that are not related to the issue. What could be happening that would cause I would appreciate any help!
package edu.gatech.cs2340.waterfall.controller;
import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.ImageView;
import com.firebase.ui.auth.AuthUI;
import com.firebase.ui.auth.IdpResponse;
import com.firebase.ui.auth.ResultCodes;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseError;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.database.Query;
import com.google.firebase.database.ValueEventListener;
import java.util.Arrays;
import edu.gatech.cs2340.waterfall.R;
import edu.gatech.cs2340.waterfall.model.Administrator;
import edu.gatech.cs2340.waterfall.model.Manager;
import edu.gatech.cs2340.waterfall.model.Model;
import edu.gatech.cs2340.waterfall.model.User;
import edu.gatech.cs2340.waterfall.model.Worker;
import static android.R.attr.data;
import static android.R.attr.dateTextAppearance;
import static android.R.attr.type;
public class WelcomeActivity extends AppCompatActivity {
private static FirebaseAuth auth;
private static final int RC_SIGN_IN = 0;
private static DatabaseReference mUserDatabase;
private static DatabaseReference mReportDatabase;
private static String type;
public static FirebaseAuth getAuth() {
return auth;
}
public static DatabaseReference getmUserDatabase() {
return mUserDatabase;
}
public static DatabaseReference getmReportDatabase() {
return mReportDatabase;
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_welcome);
ImageView myImageView = (ImageView)findViewById(R.id.logo);
Animation fade = AnimationUtils.loadAnimation(this, R.anim.fade_in);
myImageView.startAnimation(fade);
}
/**
* @param view the current view
* Open a login screen for the user
* If the user is already signed, then open the main activity
* Otherwise, open the firebase login
*/
public void openLoginScreen(View view) {
auth = FirebaseAuth.getInstance();
mUserDatabase = FirebaseDatabase.getInstance().getReference("users");
mReportDatabase = FirebaseDatabase.getInstance().getReference("Reports");
if (auth.getCurrentUser() != null) {
Log.d("LOGGED", auth.getCurrentUser().getEmail());
Intent intent = new Intent(WelcomeActivity.this, MainActivity.class);
setUser();
startActivity(intent);
finish();
} else {
//open firebase login if current user is null i.e. not signed in
startActivityForResult(AuthUI.getInstance()
.createSignInIntentBuilder()
.setProviders(Arrays.asList(new AuthUI.IdpConfig.Builder(AuthUI.EMAIL_PROVIDER).build(),
new AuthUI.IdpConfig.Builder(AuthUI.GOOGLE_PROVIDER).build(),
new AuthUI.IdpConfig.Builder(AuthUI.FACEBOOK_PROVIDER).build()))
.build(),
RC_SIGN_IN);
}
}
/**
* Retrieve the user details from firebase and set the local current user in the model
*/
public static void setUser() {
Log.d("LOGGED", "SET USER CALLED");
String uniqueId = FirebaseAuth.getInstance().getCurrentUser().getUid();
String email = FirebaseAuth.getInstance().getCurrentUser().getEmail();
Log.d("EMAIL FROM FIREBASE", email);
String name = mUserDatabase.child(uniqueId).child("name").orderByValue().toString();
int zip = mUserDatabase.child(uniqueId).child("zipcode").orderByValue().hashCode();
String phone = mUserDatabase.child(uniqueId).child("phone number").orderByValue().toString();
DatabaseReference typ = mUserDatabase.child(uniqueId).child("type");
typ.addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
Log.d("LOGGING", "Entered");
type = dataSnapshot.getValue().toString();
}
@Override
public void onCancelled(DatabaseError e) {
Log.d("Error", e.getMessage());
}
});
//make a user locally in the model
if (type.equals("user")) {
Model.getInstance().setCurrentUser(new User(uniqueId, email, name, zip, phone));
} else if (type.equals("worker")) {
Model.getInstance().setCurrentUser(new Worker(uniqueId, email, name, zip, phone));
} else if (type.equals("manager")) {
Model.getInstance().setCurrentUser(new Manager(uniqueId, email, name, zip, phone));
} else if (type.equals("admin")) {
Model.getInstance().setCurrentUser(new Administrator(uniqueId, email, name, zip, phone));
}
}
/**
* @param requestCode The request code
* @param resultCode The result code
* @param data The intent which determines the response
*
*/
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == RC_SIGN_IN) {
IdpResponse response = IdpResponse.fromResultIntent(data);
// Successfully signed in
if (resultCode == ResultCodes.OK) {
String uniqueId = FirebaseAuth.getInstance().getCurrentUser().getUid();
String email = FirebaseAuth.getInstance().getCurrentUser().getEmail();
//final String displayName = FirebaseAuth.getInstance().getCurrentUser().getDisplayName();
DatabaseReference UserRef = mUserDatabase.child(uniqueId);
UserRef.addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
Object userData = dataSnapshot.getValue();
Intent intent;
if (userData == null) {
//mUserDatabase.child(uniqueId).child("email").setValue(email);
//mUserDatabase.child(uniqueId).child("name").setValue(displayName);
intent = new Intent(WelcomeActivity.this, CreateProfile.class);
} else {
//mUserDatabase.setValue(uniqueId);
//mUserDatabase.child("email").setValue(email);
setUser();
intent = new Intent(WelcomeActivity.this, MainActivity.class);
}
startActivity(intent);
finish();
}
@Override
public void onCancelled(DatabaseError databaseError) {
}
});
Log.d("AUTH", auth.getCurrentUser().getEmail());
Intent intent = new Intent(WelcomeActivity.this, MainActivity.class);
startActivity(intent);
finish();
}
}
}
}
This is what my gradle file looks like
apply plugin: 'com.android.application'
android {
compileSdkVersion 25
buildToolsVersion "25.0.2"
defaultConfig {
applicationId "edu.gatech.cs2340.waterfall"
minSdkVersion 23
targetSdkVersion 25
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
multiDexEnabled true;
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
exclude group: 'com.android.support', module: 'support-annotations'
})
compile 'com.android.support:appcompat-v7:25.1.1'
compile 'com.android.support:design:25.1.1'
compile 'com.firebaseui:firebase-ui-auth:1.1.1'
compile 'com.android.support:multidex:1.0.1'
compile 'com.google.firebase:firebase-auth:10.0.1'
compile 'com.google.firebase:firebase-database:10.0.1'
compile 'com.google.firebase:firebase-core:10.0.1'
compile 'com.android.support.constraint:constraint-layout:1.0.1'
testCompile 'junit:junit:4.12'
}
apply plugin: 'com.google.gms.google-services'
I had the same error! What you are neglecting here is the asynchronous nature of onDataChange() and the reason nothing is logged is that there is an error before you it finishes retrieving the data. To fix this you need to implement a callback mechanism inside your onDataChange(), something like this:
public interface OnGetDataListener {
//make new interface for call back
void onSuccess(DataSnapshot dataSnapshot);
void onStart();
void onFailure();
}
Then, make a readData method to read the data from the snapShot and all this does is call the onSuccess method when data is read.
public void readData(DatabaseReference ref, final OnGetDataListener listener) {
listener.onStart();
ref.addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
listener.onSuccess(dataSnapshot);
}
@Override
public void onCancelled(DatabaseError databaseError) {
listener.onFailure();
}
});
}
Finally, in your setUser method, implement everything you needed to do in your onSuccess method. I think something like this should work.
public void setUser(DatabaseReference ref) {
readData(ref, new OnGetDataListener() {
@Override
public void onSuccess(DataSnapshot dataSnapshot) {
//whatever you need to do with the data
}
@Override
public void onStart() {
//whatever you need to do onStart
Log.d("ONSTART", "Started");
}
@Override
public void onFailure() {
}
});
}
It could be because of, you finish the current activity right after you call the setUser()
. When the response coming from firebase, the activity where the callback is in is not up. Don't kill the current activity if you come back to it. Let it stay in the stack.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With