Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Firebase onDataChange not entered

In the setUser method, I am trying to read data from my database which I will use to create an instance of User, Worker, Manager, or Administrator.I also know that the following three lines of code are incorrect, but they don't raise any errors, so they can be ignored for now.

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

What baffles me is that onDataChange is entered in onActivityResult but not in setUser. I cannot understand why onDataChange is not entered in setUser. The firebase reference is correct, and I navigated to the url logged with typ.toString() and it went to the correct entry. I also have set permissions to public, if that is relevant. I am also connected to the Internet. I also looked at other answers to similar questions which had answers that are not related to the issue. What could be happening that would cause I would appreciate any help!

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

This is what my gradle file looks like

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'
like image 596
Abhishek Tumuluru Avatar asked Mar 10 '23 17:03

Abhishek Tumuluru


2 Answers

I had the same error! What you are neglecting here is the asynchronous nature of onDataChange() and the reason nothing is logged is that there is an error before you it finishes retrieving the data. To fix this you need to implement a callback mechanism inside your onDataChange(), something like this:

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

Then, make a readData method to read the data from the snapShot and all this does is call the onSuccess method when data is read.

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

}

Finally, in your setUser method, implement everything you needed to do in your onSuccess method. I think something like this should work.

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() {

            }
        });
    }
like image 186
Mohit Chauhan Avatar answered Mar 19 '23 10:03

Mohit Chauhan


It could be because of, you finish the current activity right after you call the setUser(). When the response coming from firebase, the activity where the callback is in is not up. Don't kill the current activity if you come back to it. Let it stay in the stack.

like image 32
AtaerCaner Avatar answered Mar 19 '23 09:03

AtaerCaner