2017-03-06 32 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中調用上面的方法,並且請檢查您的數據庫路徑,這是一個有效的代碼朋友。 –