0

i try to connect to firebase to get display_name and also profile_photo for my post like instagram like this one example image but when i run my app it says that i have nullPointerException on my variable mUserAccountSettings cause my app won't run onDataChanged() or onDataCancelled() function.

i already tried to get data from mUserAccountSettings for Profile class and actually it work perfectly but in ViewFragment class it won't work

it says :

E/AndroidRuntime: FATAL EXCEPTION: main Process: com.example.jesslyn.foodylife, PID: 5655 java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String com.example.jesslyn.foodylife.FoodyLife.models.UserAccountSettings.getProfile_photo()' on a null object reference at com.example.jesslyn.foodylife.FoodyLife.Utils.ViewPostFragment.setupWidgets(ViewPostFragment.java:156) at com.example.jesslyn.foodylife.FoodyLife.Utils.ViewPostFragment.onCreateView(ViewPostFragment.java:117) at android.support.v4.app.Fragment.performCreateView(Fragment.java:2192) at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1299) at android.support.v4.app.FragmentManagerImpl.moveFragmentToExpectedState(FragmentManager.java:1528) at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1595) at android.support.v4.app.BackStackRecord.executeOps(BackStackRecord.java:758) at android.support.v4.app.FragmentManagerImpl.executeOps(FragmentManager.java:2363) at android.support.v4.app.FragmentManagerImpl.executeOpsTogether(FragmentManager.java:2149) at android.support.v4.app.FragmentManagerImpl.optimizeAndExecuteOps(FragmentManager.java:2103) at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:2013) at android.support.v4.app.FragmentManagerImpl$1.run(FragmentManager.java:710) at android.os.Handler.handleCallback(Handler.java:742) at android.os.Handler.dispatchMessage(Handler.java:95) at android.os.Looper.loop(Looper.java:154) at android.app.ActivityThread.main(ActivityThread.java:5544) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:739) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:629) E/MQSEventManagerDelegate: failed to get MQSService.

and this is my code in ViewFragment class:

package com.example.jesslyn.foodylife.FoodyLife.Utils;

import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.text.LoginFilter;
import android.util.EventLogTags;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ImageView;
import android.widget.RatingBar;
import android.widget.TextView;

import com.example.jesslyn.foodylife.FoodyLife.Utils.BottomNavigationViewHelper;
import com.example.jesslyn.foodylife.FoodyLife.Utils.FirebaseMethods;
import com.example.jesslyn.foodylife.FoodyLife.Utils.GridImageAdapter;
import com.example.jesslyn.foodylife.FoodyLife.Utils.SquareImageView;
import com.example.jesslyn.foodylife.FoodyLife.Utils.UniversalImageLoader;
import com.example.jesslyn.foodylife.FoodyLife.models.Photo;
import com.example.jesslyn.foodylife.FoodyLife.models.UserAccountSettings;
import com.example.jesslyn.foodylife.R;
import com.google.android.gms.tasks.OnCompleteListener;
import com.google.android.gms.tasks.Task;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.auth.FirebaseUser;
import com.google.firebase.auth.GetTokenResult;
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 com.ittianyu.bottomnavigationviewex.BottomNavigationViewEx;

import junit.framework.Test;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;
import java.util.TimeZone;
import java.util.concurrent.Executor;

/**
 * Created by Jesslyn on 12/4/2017.
 */

public class ViewPostFragment extends Fragment {

    private static final String TAG = "ViewPostFragment";
    private SquareImageView mPostImage;
    private BottomNavigationViewEx bottomNavigationViewEx;
    private TextView mBackLabel, mCaption, mUsername, mTimeStamp;
    private ImageView mBackArrow, mEllipses, mProfileImage;
    private RatingBar mStars;
    private String photoUrl;

    private Photo mPhoto;
    private int mActivityNumber = 0;
    private String photoUsername = "";
    private String profilePhotoUrl = "";
    private UserAccountSettings mUserAccountSettings;

    // firebase
    private FirebaseAuth mAuth;
    private FirebaseAuth.AuthStateListener mAuthListener;
    private FirebaseDatabase mFirebaseDatabase;
    private DatabaseReference myRef;
    private FirebaseMethods mFirebaseMethods;
    private String userID;
    public ViewPostFragment() {
        super();
        setArguments(new Bundle());
    }

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_view_post, container, false);
        mPostImage = (SquareImageView) view.findViewById(R.id.post_image);
        bottomNavigationViewEx = (BottomNavigationViewEx) view.findViewById(R.id.bottomNavViewBar);
        mBackArrow = (ImageView) view.findViewById(R.id.backArrow);
        mBackLabel = (TextView) view.findViewById(R.id.tvBackLabel);
        mCaption = (TextView) view.findViewById(R.id.image_caption);
        mUsername = (TextView) view.findViewById(R.id.username);
        mTimeStamp = (TextView) view.findViewById(R.id.image_time_posted);
        mEllipses = (ImageView) view.findViewById(R.id.iv_ellipses);
        mStars = (RatingBar) view.findViewById(R.id.ratingBar);

        mStars.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                RatingBar bar = (RatingBar) v;
                Log.d(TAG,"VALUE IS : "+bar.getRating()+"         **************************************************");
            }
        });
        mStars.setRating(0);
        mProfileImage = (ImageView) view.findViewById(R.id.profile_photo);

        try {
            mPhoto = getPhotoFromBundle();
            UniversalImageLoader.setImage(mPhoto.getImage_path(), mPostImage, null, "");
        } catch (NullPointerException e) {
            Log.e(TAG, "onCreateView NullPointerException : " + e.getMessage());
        }
        setupBottomNavigationView();
        setupFirebaseAuth();
        getPhotoDetails();
        setupWidgets();
        return view;
    }

    private void getPhotoDetails(){
        Log.d(TAG, "getPhotoDetails: retrieving photo details.");
        DatabaseReference reference = FirebaseDatabase.getInstance().getReference();
        Query query = reference
                .child(getString(R.string.dbname_user_account_settings))
                .orderByChild(getString(R.string.field_user_id))
                .equalTo(mPhoto.getUser_id());
        query.addListenerForSingleValueEvent(new ValueEventListener() {
            @Override
            public void onDataChange(DataSnapshot dataSnapshot) {
                Log.d(TAG, "onDataChange: ");
                for ( DataSnapshot singleSnapshot :  dataSnapshot.getChildren()){
                    Log.d(TAG, "onDataChange: " +singleSnapshot.getValue().toString());
                    mUserAccountSettings = singleSnapshot.getValue(UserAccountSettings.class);
                    Log.d(TAG, "onDataChange: "+mUserAccountSettings.getUsername());

                }
                setupWidgets();
            }

            @Override
            public void onCancelled(DatabaseError databaseError) {
                Log.d(TAG, "onCancelled: query cancelled.");
            }
        });
    }

    private void setupWidgets(){
        String timestampDiff = getTimeStampDifference();
        if(!timestampDiff.equals("0")){
           mTimeStamp.setText(timestampDiff + " DAYS AGO");
        }else{
            mTimeStamp.setText("TODAY");
        }
       UniversalImageLoader.setImage(mUserAccountSettings.getProfile_photo(), mProfileImage, null, "");
       mUsername.setText(mUserAccountSettings.getUsername());
    }


    //get how many days ago of post
    private String getTimeStampDifference() {
        Log.d(TAG, "getTimeStampDifference : getting time difference");
        String difference = "";
        Calendar c = Calendar.getInstance();
        SimpleDateFormat sdf = new SimpleDateFormat("dd-MM-yyyy'T'HH:mm:ss'Z'", Locale.ENGLISH);
        sdf.setTimeZone(TimeZone.getTimeZone("Asia/Jakarta"));
        Date timestamp;
        Date today = c.getTime();
        sdf.format(today);
        final String photoTimestamp = mPhoto.getDate_created();

        try {
            timestamp = sdf.parse(photoTimestamp);
            difference = String.valueOf(Math.round(((today.getTime() - timestamp.getTime()) / 1000 / 60 / 60 / 24)));
        } catch (ParseException e) {
            Log.e(TAG, "PARSE EXCEPTION : " + e.getMessage());
            difference = "0";
        }
        return difference;
    }

    private int getActivityFromBundle() {
        Log.d(TAG, "getActivityFromBundle arguments : " + getArguments());

        Bundle bundle = this.getArguments();
        if (bundle != null) {
            return bundle.getInt(getString(R.string.activity_number));
        } else {
            return 0;
        }
    }

    private Photo getPhotoFromBundle() {
        Log.d(TAG, "getPhotoFromBundle arguments : " + getArguments());

        Bundle bundle = this.getArguments();
        if (bundle != null) {
            return bundle.getParcelable(getString(R.string.photo));
        } else {
            return null;
        }
    }

    /**
     * BottomNavigationView setup
     */
    private void setupBottomNavigationView() {
        Log.d(TAG, "setupBottomNavigationView: setting up BottomNavigationView");
        BottomNavigationViewHelper.setupBottomNavigationView(bottomNavigationViewEx);
        BottomNavigationViewHelper.enableNavigation(getActivity(), getActivity(), bottomNavigationViewEx);
        Menu menu = bottomNavigationViewEx.getMenu();
        MenuItem menuItem = menu.getItem(mActivityNumber);
        menuItem.setChecked(true);
    }

    /**
     * ----------------------------------Firebase stuffs-----------------------------------------
     */

    //setup the firebase auth obj
    private void setupFirebaseAuth() {
        Log.d(TAG, "setupFirebaseAuth : setting up firebase auth");
        mAuth = FirebaseAuth.getInstance();
        mFirebaseDatabase = FirebaseDatabase.getInstance();
        myRef = mFirebaseDatabase.getReference();

        mAuthListener = new FirebaseAuth.AuthStateListener() {
            @Override
            public void onAuthStateChanged(@NonNull FirebaseAuth firebaseAuth) {
                FirebaseUser user = firebaseAuth.getCurrentUser();

                if (user != null) {
                    //user is signed in
                    Log.d(TAG, "user is signed in" + user.getUid());
                } else {
                    //user is signed out
                    Log.d(TAG, "onAuthStateChanged : signed out");
                }
            }
        };
    }

    @Override
    public void onStart() {
        super.onStart();
        mAuth.addAuthStateListener(mAuthListener);

    }

    @Override
    public void onStop() {
        super.onStop();
        if (mAuthListener != null) {
            mAuth.removeAuthStateListener(mAuthListener);
        }
    }
}
Alex Mamo
  • 130,605
  • 17
  • 163
  • 193
  • Possible duplicate of [What is a NullPointerException, and how do I fix it?](https://stackoverflow.com/questions/218384/what-is-a-nullpointerexception-and-how-do-i-fix-it) – Peter Haddad Dec 07 '17 at 12:49
  • Leaving open but needs changing, OP is not asking to fix the NPE but seems to be asking why his code does not run onDataChanged() or onDataCancelled() – Kelly S. French Dec 07 '17 at 17:29

1 Answers1

1

It is because the variable mUserAccountSettings is initialized in onDataChange() method which is a callback and is executed async. Before this it initialized your main thread is trying to access that in setupWidgets()

A possible fix would be to move the below code from setupWidgets() to onDataChange().

 UniversalImageLoader.setImage(mUserAccountSettings.getProfile_photo(), mProfileImage, null, "");

NOTE: this is not intend to show you any best practice. This solution is just to show that all UI updates which depends on value from server, should happen ones you get the response from server.

Chandra Sekhar
  • 18,914
  • 16
  • 84
  • 125