Search code examples
javaandroidgoogle-cloud-firestorefragmentviewmodel

How to retrieve data from firebase cloud store to a fragment class for example ProfileFragment.class which also uses MVVM?


I am a newbie. Tried other resources but most of them have discussed on recycler view but for my app I am using view model. Looking forward for help. I want to retrieve the user profile data from firebase cloud store. Following is the code I referred so far.

ProfileViewModel.java

import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.ViewModel;

public class ProfileViewModel extends ViewModel {

private MutableLiveData<String> mText;

public ProfileViewModel() {
    mText = new MutableLiveData<>();

    mText.setValue( "Your Profile" );
}

public LiveData<String> getText() {
    return mText;
}

}

ProfileFragment.java

import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProviders;

import com.example.parkbookingslot.R;

public class ProfileFragment extends Fragment {

private ProfileViewModel profileViewModel;

public View onCreateView(@NonNull LayoutInflater inflater,
                         ViewGroup container, Bundle savedInstanceState) {
    profileViewModel =
            ViewModelProviders.of( this ).get( ProfileViewModel.class );
    View root = inflater.inflate( R.layout.fragment_profile, container, false );

    final TextView textView = root.findViewById( R.id.text_profile );

    profileViewModel.getText().observe( getViewLifecycleOwner(), new Observer<String>() {
        @Override
        public void onChanged(@Nullable String s) {
            textView.setText( s );
        }
    } );

    return root;
}

}

fragment_profile.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
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"
tools:context=".ui.profile.ProfileFragment">

<TextView
    android:id="@+id/email"
    android:layout_width="84dp"
    android:layout_height="31dp"
    android:layout_marginEnd="164dp"
    android:layout_marginRight="164dp"
    android:layout_marginBottom="182dp"
    android:text="Email"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintEnd_toEndOf="parent" />

<TextView
    android:id="@+id/text_profile"
    android:layout_width="109dp"
    android:layout_height="35dp"
    android:layout_marginEnd="150dp"
    android:layout_marginRight="150dp"
    android:layout_marginBottom="35dp"
    android:text="Your Profile"
    app:layout_constraintBottom_toTopOf="@+id/name"
    app:layout_constraintEnd_toEndOf="parent" />

<TextView
    android:id="@+id/name"
    android:layout_width="84dp"
    android:layout_height="31dp"
    android:layout_marginEnd="164dp"
    android:layout_marginRight="164dp"
    android:layout_marginBottom="34dp"
    android:text="Name"
    app:layout_constraintBottom_toTopOf="@+id/phoneno"
    app:layout_constraintEnd_toEndOf="parent" />

<TextView
    android:id="@+id/phoneno"
    android:layout_width="wrap_content"
    android:layout_height="31dp"
    android:layout_marginEnd="158dp"
    android:layout_marginRight="158dp"
    android:layout_marginBottom="36dp"
    android:text="Phone Number"
    app:layout_constraintBottom_toTopOf="@+id/vehicleno"
    app:layout_constraintEnd_toEndOf="parent" />

<TextView
    android:id="@+id/vehicleno"
    android:layout_width="112dp"
    android:layout_height="35dp"
    android:layout_marginEnd="150dp"
    android:layout_marginRight="150dp"
    android:layout_marginBottom="30dp"
    android:text="Vehicle Number"
    app:layout_constraintBottom_toTopOf="@+id/email"
    app:layout_constraintEnd_toEndOf="parent" />

Edited Code after applying the solution shared;

package com.example.parkbookingslot.ui.profile;

import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProviders;

import com.example.parkbookingslot.R;
import com.example.parkbookingslot.UserProfile;

public class ProfileFragment extends Fragment {

    private ProfileViewModel profileViewModel;

    public View onCreateView(@NonNull LayoutInflater inflater,
                         ViewGroup container, Bundle  savedInstanceState) {

    final View root = inflater.inflate( R.layout.fragment_profile, container, false );
    profileViewModel = ViewModelProviders.of( this ).get( ProfileViewModel.class );

    profileViewModel.getUserProfile().observe(getViewLifecycleOwner(), new Observer<UserProfile>() {
        @Override
        public void onChanged(UserProfile userProfile) {
            if (userProfile != null) {
                ((TextView) root.findViewById(R.id.name)).setText(userProfile.getName());
                ((TextView) root.findViewById(R.id.phoneno)).setText(userProfile.getPhoneno());
                ((TextView) root.findViewById(R.id.vehicleno)).setText(userProfile.getVehicleno());
                ((TextView) root.findViewById(R.id.email)).setText(userProfile.getEmail());
            }else {
                Toast toast = Toast.makeText(getActivity().getApplicationContext(), "No user information", Toast.LENGTH_SHORT);
                toast.show();
            }
        }
    });
    return root;
}

}

Before the edited code, I get the following screen.
After updating the UI, I get the following screen;

Did I miss something in fragment_profile.xml or it's in ProfileFragment.java?

Edited ProfileViewModel.java

package com.example.parkbookingslot.ui.profile;

import androidx.annotation.NonNull;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.ViewModel;

import com.example.parkbookingslot.UserProfile;
import com.google.android.gms.tasks.OnCompleteListener;
import com.google.android.gms.tasks.Task;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.firestore.DocumentReference;
import com.google.firebase.firestore.DocumentSnapshot;
import com.google.firebase.firestore.FirebaseFirestore;

public class ProfileViewModel extends ViewModel {
    FirebaseAuth fAuth = FirebaseAuth.getInstance();
    String userId = fAuth.getCurrentUser().getUid();

    public LiveData<UserProfile> getUserProfile() {
     final MutableLiveData<UserProfile> userProfileMutableLiveData =    new MutableLiveData<>();
     FirebaseFirestore db = FirebaseFirestore.getInstance();

     DocumentReference docRef =  db.collection("Users").document(userId);
     docRef.get().addOnCompleteListener(new  OnCompleteListener<DocumentSnapshot>() {
        @Override
        public void onComplete(@NonNull Task<DocumentSnapshot> task) {
            if (task.isSuccessful()) {
                DocumentSnapshot documentSnapshot = task.getResult();
                if (documentSnapshot != null &&  documentSnapshot.exists()) {
                    UserProfile userProfile =  documentSnapshot.toObject(UserProfile.class);
                    userProfileMutableLiveData.postValue(userProfile);
                }else {
                    userProfileMutableLiveData.postValue(null);
                }
            }else {
                userProfileMutableLiveData.postValue(null);
            }
        }
    });
    return userProfileMutableLiveData;
}

}

Data in firebase cloudstore


Solution

  • ViewModel

    import androidx.lifecycle.LiveData;
    import androidx.lifecycle.MutableLiveData;
    import androidx.lifecycle.ViewModel;
    
    public class ProfileViewModel extends ViewModel {
    
          public LiveData<UserProfile> getUserProfile(){
    
            final MutableLiveData<UserProfile> userProfileMutableLiveData = new MutableLiveData<>();
            FirebaseFirestore db = FirebaseFirestore.getInstance();
            DocumentReference docRef = db.collection("users").document("android.dev@gmail.com");
            docRef.get().addOnCompleteListener(new OnCompleteListener<DocumentSnapshot>() {
                @Override
                public void onComplete(@NonNull Task<DocumentSnapshot> task) {
                    if (task.isSuccessful()) {
                        DocumentSnapshot document = task.getResult();
                        if (document != null && document.exists()) {
                            UserProfile userProfile = document.toObject(UserProfile.class);
                            userProfileMutableLiveData.postValue(userProfile);
                        } else {
                            userProfileMutableLiveData.postValue(null);
                        }
                    } else {
                        userProfileMutableLiveData.postValue(null);
                    }
                }
            });
    
            return userProfileMutableLiveData;
        }
    }
    
    

    Fragment

    import android.os.Bundle;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.view.ViewGroup;
    import android.widget.TextView;
    
    import androidx.annotation.NonNull;
    import androidx.annotation.Nullable;
    import androidx.fragment.app.Fragment;
    import androidx.lifecycle.Observer;
    import androidx.lifecycle.ViewModelProviders;
    
    import com.example.parkbookingslot.R;
    
    public class ProfileFragment extends Fragment {
    
    private ProfileViewModel profileViewModel;
    
    public View onCreateView(@NonNull LayoutInflater inflater,
                             ViewGroup container, Bundle savedInstanceState) {
    
        View root = inflater.inflate( R.layout.fragment_profile, container, false );
    
        profileViewModel =  ViewModelProviders.of(this).get(ProfileViewModel.class);
    
        profileViewModel.getUserProfile().observe(getViewLifecycleOwner(),new Observer<UserProfile>(){
             @Override
             public void onChanged(UserProfile userProfile) {
                    if(userProfile != null){
                        //UPDATE YOUR UI HERE
                    } else {
                        //SHOW ERROR MESSAGE
                    }
             }
        });
    
        return root;
    }
    
    

    User Profile Model

    public class UserProfile {
        String fullName, address, gender, phone;
    
        public String getFullName() {
            return fullName;
        }
    
        public void setFullName(String fullName) {
            this.fullName = fullName;
        }
    
        public String getAddress() {
            return address;
        }
    
        public void setAddress(String address) {
            this.address = address;
        }
    
        public String getGender() {
            return gender;
        }
    
        public void setGender(String gender) {
            this.gender = gender;
        }
    
        public String getPhone() {
            return phone;
        }
    
        public void setPhone(String phone) {
            this.phone = phone;
        }
    }
    
    

    Firestore View

    enter image description here