未输入Firebase onDataChange

时间:2017-03-06 09:28:48

标签: android firebase firebase-realtime-database

在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是在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 个答案:

答案 0 :(得分:5)

我有同样的错误!你在这里忽略的是onDataChange()的异步性质以及没有记录的原因是在你完成检索数据之前有一个错误。要解决这个问题,你需要在onDataChange()中实现一个回调机制,如下所示:

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

然后,使用readData方法从snapShot读取数据,所有这些都是在读取数据时调用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 :(得分:2)

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

答案 2 :(得分:0)

使用addlistenerforsinglevalueevent:实现onDataChangeMethod,如果为您提供该特定节点的dataScreenShot。

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

答案 3 :(得分: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;`