0

I have a grid layout with 4 cardviews and I have data in firebase database to be displayed in the cards. The data retrived from Firebase is stored in a class. The thing is I'cant use getter functions and display the data in setText. Whenver I do the app crashes. It is a fragment.

Here is the fragment :

public class HomeFragment extends Fragment {

usageData fetcheduserdata;
private DatabaseReference uidDatabase;
private DatabaseReference rootDatabase;
View v;
FirebaseAuth mAuth;
FirebaseUser mUser;
RecyclerView recyclerView;


@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
    View view =  inflater.inflate(R.layout.fragment_home,container,false);
    return view;
}

@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);
    this.v = view;
    getActivity().setTitle("Home");

    mUser = mAuth.getInstance().getCurrentUser();

    TextView userPoints = (TextView) view.findViewById(R.id.user_points);
    TextView userAdrequests = (TextView) view.findViewById(R.id.user_adrequests);
    TextView userClicks =  (TextView) view.findViewById(R.id.user_adclick);
    TextView userRedeemthreshold =  (TextView) view.findViewById(R.id.user_rthreshold);



    final String uid = FirebaseAuth.getInstance().getCurrentUser().getUid();
    rootDatabase = FirebaseDatabase.getInstance().getReference();
    uidDatabase = rootDatabase.child("Data").child(uid);
    ValueEventListener valueEventListener = new ValueEventListener() {
        @Override
        public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
            Integer up = dataSnapshot.child("userPoints").getValue(Integer.class);
            Integer ua = dataSnapshot.child("userAdrequests").getValue(Integer.class);
            Integer uc = dataSnapshot.child("userClicks").getValue(Integer.class);
            Integer ur = dataSnapshot.child("userRedeemthreshold").getValue(Integer.class);
            fetcheduserdata =  new usageData(uid,up,ua,uc,ur);
            Toast.makeText(getActivity(), "Fetched UsageData From Firebase", Toast.LENGTH_SHORT).show();

        }


        @Override
        public void onCancelled(@NonNull DatabaseError databaseError) {
            Toast.makeText(getActivity(), "UsageData Error", Toast.LENGTH_SHORT).show();
        }
    };

    uidDatabase.addValueEventListener(valueEventListener);
    userPoints.setText(String.valueOf(fetcheduserdata.getUserPoints()));
    userAdrequests.setText(fetcheduserdata.getUserAdrequests());
    userClicks.setText(fetcheduserdata.getUserClicks());
    userRedeemthreshold.setText(fetcheduserdata.getUserPoints());
}
}

XML File :

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:weightSum="10"
tools:context=".HomeFragment">

<!-- TODO: Update blank fragment layout -->

<RelativeLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_weight="2">


    <TextView
        android:id="@+id/textView5"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:text="Your Performance"
        android:textSize="24sp"
        android:textStyle="italic" />
</RelativeLayout>


<GridLayout
    android:layout_width="match_parent"
    android:layout_height="0dp"
    android:layout_weight="8"
    android:alignmentMode="alignMargins"
    android:columnCount="2"
    android:columnOrderPreserved="false"
    android:padding="14dp"
    android:rowCount="2">

    <android.support.v7.widget.CardView
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:layout_columnWeight="1"
        android:layout_marginBottom="16dp"
        android:layout_marginLeft="16dp"
        android:layout_marginRight="16dp"
        android:layout_rowWeight="1"
        app:cardCornerRadius="8dp"
        app:cardElevation="8dp">

        <android.support.constraint.ConstraintLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_gravity="center_horizontal|center_vertical"
            android:layout_margin="16dp"
            android:orientation="vertical">

            <android.support.constraint.Guideline
                android:id="@+id/guideline"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:orientation="horizontal"
                app:layout_constraintGuide_percent="0.75" />

            <TextView
                android:id="@+id/user_points"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginBottom="8dp"
                android:layout_marginEnd="8dp"
                android:layout_marginStart="8dp"
                android:layout_marginTop="8dp"
                android:gravity="center_vertical|center_horizontal"
                android:text="0"
                android:textAlignment="center"
                android:textSize="24sp"
                android:textStyle="bold"
                app:layout_constraintBottom_toTopOf="@+id/guideline"
                app:layout_constraintEnd_toEndOf="parent"
                app:layout_constraintStart_toStartOf="parent"
                app:layout_constraintTop_toTopOf="parent" />

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginBottom="8dp"
                android:layout_marginEnd="8dp"
                android:layout_marginStart="8dp"
                android:layout_marginTop="8dp"
                android:gravity="center_horizontal"
                android:text="Points"
                app:layout_constraintBottom_toBottomOf="parent"
                app:layout_constraintEnd_toEndOf="parent"
                app:layout_constraintStart_toStartOf="parent"
                app:layout_constraintTop_toTopOf="@+id/guideline" />

        </android.support.constraint.ConstraintLayout>

    </android.support.v7.widget.CardView>

    <android.support.v7.widget.CardView
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:layout_columnWeight="1"
        android:layout_marginBottom="16dp"
        android:layout_marginLeft="16dp"
        android:layout_marginRight="16dp"
        android:layout_rowWeight="2"
        app:cardCornerRadius="8dp"
        app:cardElevation="8dp">

        <android.support.constraint.ConstraintLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_gravity="center_horizontal|center_vertical"
            android:layout_margin="16dp"
            android:orientation="vertical">

            <android.support.constraint.Guideline
                android:id="@+id/guideline3"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:orientation="horizontal"
                app:layout_constraintGuide_percent="0.75" />

            <TextView
                android:id="@+id/user_adrequests"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginBottom="8dp"
                android:layout_marginEnd="8dp"
                android:layout_marginStart="8dp"
                android:layout_marginTop="8dp"
                android:gravity="center_vertical|center_horizontal"
                android:text="0"
                android:textAlignment="center"
                android:textSize="24sp"
                android:textStyle="bold"
                app:layout_constraintBottom_toTopOf="@+id/textView6"
                app:layout_constraintEnd_toEndOf="parent"
                app:layout_constraintStart_toStartOf="parent"
                app:layout_constraintTop_toTopOf="parent" />

            <TextView
                android:id="@+id/textView6"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginBottom="8dp"
                android:layout_marginEnd="8dp"
                android:layout_marginStart="8dp"
                android:gravity="center_horizontal"
                android:text="Ad Requests"
                app:layout_constraintBottom_toBottomOf="parent"
                app:layout_constraintEnd_toEndOf="parent"
                app:layout_constraintStart_toStartOf="parent" />

        </android.support.constraint.ConstraintLayout>

    </android.support.v7.widget.CardView>

    <android.support.v7.widget.CardView
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:layout_columnWeight="2"
        android:layout_marginBottom="16dp"
        android:layout_marginLeft="16dp"
        android:layout_marginRight="16dp"
        android:layout_rowWeight="1"
        app:cardCornerRadius="8dp"
        app:cardElevation="8dp">


        <android.support.constraint.ConstraintLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_gravity="center_horizontal|center_vertical"
            android:layout_margin="16dp"
            android:orientation="vertical">

            <android.support.constraint.Guideline
                android:id="@+id/guideline5"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:orientation="horizontal"
                app:layout_constraintGuide_percent="0.75" />

            <TextView
                android:id="@+id/user_adclick"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginBottom="8dp"
                android:layout_marginEnd="8dp"
                android:layout_marginStart="8dp"
                android:layout_marginTop="8dp"
                android:gravity="center_vertical|center_horizontal"
                android:text="0"
                android:textAlignment="center"
                android:textSize="24sp"
                android:textStyle="bold"
                app:layout_constraintBottom_toTopOf="@+id/guideline5"
                app:layout_constraintEnd_toEndOf="parent"
                app:layout_constraintStart_toStartOf="parent"
                app:layout_constraintTop_toTopOf="parent" />

            <TextView
                android:id="@+id/textView3"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginBottom="8dp"
                android:layout_marginEnd="8dp"
                android:layout_marginStart="8dp"
                android:gravity="center_horizontal"
                android:text="Ad Clicks"
                app:layout_constraintBottom_toBottomOf="parent"
                app:layout_constraintEnd_toEndOf="parent"
                app:layout_constraintStart_toStartOf="parent" />

        </android.support.constraint.ConstraintLayout>
    </android.support.v7.widget.CardView>

    <android.support.v7.widget.CardView
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:layout_columnWeight="2"
        android:layout_marginBottom="16dp"
        android:layout_marginLeft="16dp"
        android:layout_marginRight="16dp"
        android:layout_rowWeight="2"
        app:cardCornerRadius="8dp"
        app:cardElevation="8dp">

        <android.support.constraint.ConstraintLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_gravity="center_horizontal|center_vertical"
            android:layout_margin="16dp"
            android:orientation="vertical">

            <android.support.constraint.Guideline
                android:id="@+id/guideline6"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:orientation="horizontal"
                app:layout_constraintGuide_percent="0.75" />

            <TextView
                android:id="@+id/user_rthreshold"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginBottom="8dp"
                android:layout_marginEnd="8dp"
                android:layout_marginStart="8dp"
                android:layout_marginTop="8dp"
                android:gravity="center_vertical|center_horizontal"
                android:text="0%"
                android:textAlignment="center"
                android:textSize="24sp"
                android:textStyle="bold"
                app:layout_constraintBottom_toTopOf="@+id/textView7"
                app:layout_constraintEnd_toEndOf="parent"
                app:layout_constraintStart_toStartOf="parent"
                app:layout_constraintTop_toTopOf="parent" />

            <TextView
                android:id="@+id/textView7"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginBottom="8dp"
                android:layout_marginEnd="8dp"
                android:layout_marginStart="8dp"
                android:gravity="center_horizontal"
                android:text="Redeem Threshold"
                app:layout_constraintBottom_toBottomOf="parent"
                app:layout_constraintEnd_toEndOf="parent"
                app:layout_constraintStart_toStartOf="parent" />

        </android.support.constraint.ConstraintLayout>

    </android.support.v7.widget.CardView>
</GridLayout>

Here is the class UsageData :

package com.balaji.earnyourself;

public class usageData {
String userId;
Integer userPoints,userAdrequests,userClicks,userRedeemthreshold;

public usageData(String userId, Integer userPoints, Integer userAdrequests, Integer userClicks, Integer userRedeemthreshold) {
    this.userId = userId;
    this.userPoints = userPoints;
    this.userAdrequests = userAdrequests;
    this.userClicks = userClicks;
    this.userRedeemthreshold = userRedeemthreshold;
}

public usageData(String userId) {
    this.userId = userId;
    this.userPoints = 0;
    this.userAdrequests = 0;
    this.userClicks = 0;
    this.userRedeemthreshold = 0;
}

public String getUserId() {
    return userId;
}

public void setUserId(String userId) {
    this.userId = userId;
}

public int getUserPoints() {
    return userPoints;
}

public void setUserPoints(int userPoints) {
    this.userPoints = userPoints;
}

public int getUserAdrequests() {
    return userAdrequests;
}

public void setUserAdrequests(int userAdrequests) {
    this.userAdrequests = userAdrequests;
}

public int getUserClicks() {
    return userClicks;
}

public void setUserClicks(int userClicks) {
    this.userClicks = userClicks;
}

public int getUserRedeemthreshold() {
    return userRedeemthreshold;
}

public void setUserRedeemthreshold(int userRedeemthreshold) {
    this.userRedeemthreshold = userRedeemthreshold;
}
}

How to get through this ? I've tried the ways that I know but I couldn't get it to work.

Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
Balu Sk
  • 13
  • 4

1 Answers1

0

Firebase APIs are asynchronous, meaning that onDataChange() method returns immediately after it's invoked, and the callback from the Task it returns, will be called some time later. There are no guarantees about how long it will take. So it may take from a few hundred milliseconds to a few seconds before that data is available. Because that method returns immediately, the value of your fetcheduserdata variable you're trying to use it outside the onDataChange() method, will not have been assigned from the callback yet.

Basically, you're trying to use a value synchronously from an API that's asynchronous. That's not a good idea. You should handle the APIs asynchronously as intended.

A quick solve for this problem would be to move the following lines inside the onDataChange() method right after you toast that message:

userPoints.setText(String.valueOf(fetcheduserdata.getUserPoints()));
userAdrequests.setText(fetcheduserdata.getUserAdrequests());
userClicks.setText(fetcheduserdata.getUserClicks());
userRedeemthreshold.setText(fetcheduserdata.getUserPoints());

Otherwise I recommend you see the last part of my anwser from this post in which I have explained how it can be done using a custom callback. You can also take a look at this video for a better understanding.

Note that there is no need to create a new object of usageData in order to get the data back, you can simply use:

userPoints.setText(String.valueOf(up));
Alex Mamo
  • 130,605
  • 17
  • 163
  • 193