2017-03-06 64 views
2

在setUser方法中,我试图从我的数据库中读取数据,我将使用它创建User,Worker,Manager或Administrator的实例。我也知道以下三行代码是不正确,但他们不会提出任何错误,所以现在可以忽略它们。未输入Firebase onDataChange

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是在onActivityResult中输入的,但没有在setUser中输入。我不明白为什么没有在setUser中输入onDataChange。 firebase引用是正确的,我导航到用typ.toString()记录的url,并且它转到正确的条目。如果这是相关的,我也设置了公开权限。我也连接到互联网。我还查看了与问题无关的类似问题的其他答案。 会发生什么,会导致我将不胜感激任何帮助!

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(); 
      } 
     } 
    } 
} 

这是我的gradle这个文件看起来像

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' 

回答

4

我有同样的错误!你在这里忽略的是onDataChange()的异步特性和没有任何记录的原因是在你完成检索数据之前有一个错误。为了解决这个问题,你需要实现你的onDataChange内回调机制(),像这样:

public interface OnGetDataListener { 
    //make new interface for call back 
    void onSuccess(DataSnapshot dataSnapshot); 
    void onStart(); 
    void onFailure(); 
} 

然后,做一个READDATA方法来读取从快照中的数据而这一切确实是调用时的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() { 

      } 
     }); 
    } 
+1

非常感谢。我明白为什么问题出现在那里。这固定了一切!我已经呆了好几个小时了! –

0

使用addlistenerforsinglevalueevent:实施onDataChangeMethod如果您提供特定节点的dataScreenShot。

注意:如果您使用Firebase的离线功能,请不要忘记使用keepSync(true);

+0

这正是我所做的。你能看看代码吗?特别是setUser方法。 –

+0

只要改变事件addValueEventListener如果它进入然后可能我知道这个问题,否则需要再次分析 –

+0

我试图做到这一点,如上面的评论显示没有成功。这不等于拥有匿名内部类吗? –

1

可能是因为您在拨打setUser()后立即完成当前活动。当来自firebase的响应中,回调所在的活动未启动。如果你回来,不要杀死当前的活动。让它留在堆栈中。

+0

感谢您的回复。我删除了两个完成()调用,我得到了和以前一样的错误。我的变量“type”(private static String type)仍然为null,并且在“if(type.equals(”user“))”中导致nullpointerexception,因为它没有在onDataChange中初始化。 –

+0

公开您的“类型”变量。也许dataSnapshot在试图转换时无法访问模型中的变量,并导致nullpointer exp。你一定要用'dataSnapshot.getValue()'得到你想要的确切数据。 – AtaerCaner

+0

我收到了同样的错误。此外,问题是我有一个日志。d在onDataChange中,但它永远不会被记录,因为onDataChange永远不会被输入! –

0

尝试这样`

ValueEventListener postListener = new ValueEventListener() { 
     @Override 
     public void onDataChange(DataSnapshot dataSnapshot) { 
      // Get Post object and use the values to update the UI 

      for (DataSnapshot postSnapshot : dataSnapshot.getChildren()) { 
       String value = postSnapshot.getValue(); 
      } 
     } 

     @Override 
     public void onCancelled(DatabaseError databaseError) { 
      // Getting Post failed, log a message 
      // [START_EXCLUDE] 
      Toast.makeText(ClassName.this, "Failed to load post.", 
        Toast.LENGTH_SHORT).show(); 
      // [END_EXCLUDE] 
     } 
    }; 
    mPostReference.addValueEventListener(postListener); 
    mPostListener = postListener;` 
+0

我收到了同样的结果。 onDataChange未被输入:/ –

+0

在OnCreate中启动mPostReference并在onStart中调用上面的方法,并且请检查您的数据库路径,这是一个有效的代码朋友。 –