在setuser方法中,我试图从数据库中读取数据,我将使用这些数据创建user、worker、manager或administrator的实例。我还知道以下三行代码是不正确的,但它们不会引发任何错误,因此现在可以忽略它们。
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();
令我困惑的是ondatachange是在onactiveyresult中输入的,而不是在setuser中。我不明白为什么在setuser中没有输入ondatachange。firebase引用是正确的,我导航到用typ.tostring()记录的url,它转到了正确的条目。如果相关的话,我还设置了public的权限。我还可以上网。我还研究了其他类似问题的答案,这些问题的答案与问题无关。
如果发生什么事,我会非常感谢你的帮助!
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();
}
}
}
}
这就是我的毕业档案
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'
最佳答案
我也犯了同样的错误!这里您忽略的是ondatachange()的异步特性,而不记录任何内容的原因是在它完成数据检索之前有一个错误。要解决此问题,需要在onDataChange()中实现回调机制,如下所示:
public interface OnGetDataListener {
//make new interface for call back
void onSuccess(DataSnapshot dataSnapshot);
void onStart();
void onFailure();
}
然后,创建一个read data方法从快照中读取数据,这样做的目的就是在读取数据时调用onSuccess方法。
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();
}
});
}
最后,在setuser方法中,实现onSuccess方法中需要执行的所有操作。我想这样的办法应该行得通。
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() {
}
});
}