未输入Firebase onDataChange

Abh*_*uru 4 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();
Run Code Online (Sandbox Code Playgroud)

令我困惑的是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();
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

这就是我的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'
Run Code Online (Sandbox Code Playgroud)

Moh*_*han 5

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

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

然后,创建一个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();
        }
    });

}
Run Code Online (Sandbox Code Playgroud)

最后,在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() {

            }
        });
    }
Run Code Online (Sandbox Code Playgroud)