<file_sep>package com.project.roadsideassistant.ui.fragments.review;

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

import com.project.roadsideassistant.data.models.Message;
import com.project.roadsideassistant.data.repositories.MessageRepository;

public class ReviewViewModel extends ViewModel implements MessageRepository.MessageTaskListener {

    private MessageRepository messageRepository = new MessageRepository(this);

    private MutableLiveData<String> _successMessage = new MutableLiveData<>();
    private MutableLiveData<String> _errorMessage = new MutableLiveData<>();

    public ReviewViewModel() {
    }

    public void addMessage(Message message) {
        messageRepository.add(message);
    }

    public LiveData<String> getSuccessMessage() {
        return _successMessage;
    }

    public LiveData<String> getErrorMessage() {
        return _errorMessage;
    }

    @Override
    public void onComplete(String message) {
        _successMessage.setValue(message);
    }

    @Override
    public void onError(Exception exception) {
        _errorMessage.setValue(exception.getLocalizedMessage());
    }
}
<file_sep>package com.project.roadsideassistant.ui.fragments.notifications;

import androidx.annotation.NonNull;
import androidx.lifecycle.ViewModel;
import androidx.lifecycle.ViewModelProvider;

import java.lang.reflect.InvocationTargetException;

public class NotificationViewModelFactory implements ViewModelProvider.Factory {

    private String userId;

    public NotificationViewModelFactory(String userId) {
        this.userId = userId;
    }

    @NonNull
    @Override
    public <T extends ViewModel> T create(@NonNull Class<T> modelClass) {
        try {

            return modelClass.getConstructor(String.class).newInstance(userId);

        } catch (NoSuchMethodException | IllegalAccessException | InstantiationException | InvocationTargetException e) {
            e.printStackTrace();
            return null;
        }
    }
}
<file_sep>package com.project.roadsideassistant.data.repositories;

import android.util.Log;

import com.google.firebase.firestore.FirebaseFirestore;
import com.project.roadsideassistant.data.models.Product;

import java.util.List;

public class ProductsRepository {
    private static final String TAG = "ProductsRepository";

    private FirebaseFirestore mDatabase;

    private ProductTaskListener taskListener;

    public ProductsRepository(ProductTaskListener taskListener) {
        mDatabase = FirebaseFirestore.getInstance();
        this.taskListener = taskListener;
    }

    public void getProducts() {
        mDatabase.collection("products")
                .addSnapshotListener((queryDocumentSnapshots, e) -> {

                    if (e != null) {
                        Log.e(TAG, "getProducts: Products", e);
                        assert taskListener != null;
                        taskListener.showError(e.getLocalizedMessage());
                        return;
                    }

                    Log.d(TAG, "getProducts: Successful we are good to go => count: " + queryDocumentSnapshots.size());

                    taskListener.showProducts(queryDocumentSnapshots.toObjects(Product.class));

                });
    }

    public interface ProductTaskListener {

        void showProducts(List<Product> products);

        void showError(String message);
    }
}
<file_sep>include ':app'
rootProject.name='RoadSideAssistant'
<file_sep>package com.project.roadsideassistant.utils;

import android.view.View;
import android.widget.Toast;

import com.google.android.material.snackbar.Snackbar;
import com.project.roadsideassistant.RoadAssistantApplication;

public class UIHelpers {

    public static void toast(String message) {
        Toast.makeText(RoadAssistantApplication.getInstance(), message, Toast.LENGTH_SHORT).show();
    }

    public static void snackbar(View view, String message) {
        Snackbar.make(view, message, Snackbar.LENGTH_LONG).setAction("OK", v -> {
        }).show();
    }
}
<file_sep>package com.project.roadsideassistant.ui.fragments.profile;

import androidx.lifecycle.ViewModelProvider;
import androidx.lifecycle.ViewModelProviders;

import android.content.Context;
import android.os.Bundle;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.navigation.Navigation;

import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import com.bumptech.glide.Glide;
import com.google.android.material.button.MaterialButton;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.auth.FirebaseUser;
import com.project.roadsideassistant.R;

import de.hdodenhof.circleimageview.CircleImageView;

public class ProfileFragment extends Fragment {

    private ProfileViewModel mViewModel;
    private FirebaseAuth mAuth;
    private FirebaseUser currentUser;

    private CircleImageView avatarCIV;
    private TextView displayNameTV, emailTV, phoneTV, emailNotVerifiedTV;
    private MaterialButton setupAccountButton;

    public static ProfileFragment newInstance() {
        return new ProfileFragment();
    }

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

    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);

        //Register the vies associated
        displayNameTV = view.findViewById(R.id.display_name_tv);
        emailTV = view.findViewById(R.id.email_tv);
        phoneTV = view.findViewById(R.id.phone_tv);
        emailNotVerifiedTV = view.findViewById(R.id.email_not_verified_tv);
        setupAccountButton = view.findViewById(R.id.setup_account_button);
        avatarCIV = view.findViewById(R.id.avatar_civ);

        setupAccountButton.setOnClickListener(v -> {
            Navigation.findNavController(v).navigate(R.id.action_profileFragment_to_setupAccountFragment);
        });

        //Load the image to the image view
        Glide.with(this)
                .load(currentUser.getPhotoUrl())
                .centerCrop()
                .placeholder(R.drawable.ic_account_circle_white)
                .into(avatarCIV);

        //Set display Name
        if (!TextUtils.isEmpty(currentUser.getDisplayName())) {
            displayNameTV.setText(currentUser.getDisplayName());
        }

        //Setting the authenticated email address
        emailTV.setText(currentUser.getEmail());

        //Check user phone number
        if (!TextUtils.isEmpty(currentUser.getPhoneNumber())) {
            phoneTV.setText(currentUser.getPhoneNumber());
        }

        //Checking whether whether the authenticated user email is verified and display or hiding the barge if necessary
        if (currentUser.isEmailVerified()) {
            emailNotVerifiedTV.setVisibility(View.INVISIBLE);
        } else {
            emailNotVerifiedTV.setVisibility(View.VISIBLE);
        }

    }

    @Override
    public void onActivityCreated(@Nullable Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        mViewModel = new ViewModelProvider(this).get(ProfileViewModel.class);
    }

    @Override
    public void onAttach(@NonNull Context context) {
        super.onAttach(context);

        mAuth = FirebaseAuth.getInstance();

        currentUser = mAuth.getCurrentUser();
    }
}
<file_sep>package com.project.roadsideassistant.ui.fragments.products;

import android.util.Log;

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

import com.project.roadsideassistant.data.models.Product;
import com.project.roadsideassistant.data.repositories.ProductsRepository;

import java.util.List;

public class ProductsViewModel extends ViewModel implements ProductsRepository.ProductTaskListener {

    private static final String TAG = "ProductsViewModel";

    private ProductsRepository productsRepository;

    private MutableLiveData<List<Product>> _products = new MutableLiveData<>();

    public ProductsViewModel() {

        productsRepository = new ProductsRepository(this);
        productsRepository.getProducts();
    }

    public LiveData<List<Product>> getProducts() {
        return _products;
    }

    @Override
    public void showProducts(List<Product> products) {
        Log.d(TAG, "showProducts: products size" + products.size());
        _products.setValue(products);
    }

    @Override
    public void showError(String message) {
        Log.d(TAG, "showError: viewmodel" + message);
        //Show error
    }
}
<file_sep>package com.project.roadsideassistant.ui.fragments.gethelp.products;

import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.ViewModelProvider;
import androidx.navigation.Navigation;
import androidx.recyclerview.widget.DividerItemDecoration;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import com.project.roadsideassistant.R;
import com.project.roadsideassistant.data.models.Message;

public class ChooseProductFragment extends Fragment {
    private static final String TAG = "ChooseProductFragment";

    private ChooseProductAdapter chooseProductAdapter;
    private RecyclerView productsRecyclerView;
    private Message message;

    public ChooseProductFragment() {
    }

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        assert getArguments() != null;
        //The the message argument first
        message = ChooseProductFragmentArgs.fromBundle(getArguments()).getMessage();
    }

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

    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);

        assert getContext() != null;

        productsRecyclerView = view.findViewById(R.id.products_recycler_view);
        productsRecyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
        productsRecyclerView.addItemDecoration(new DividerItemDecoration(getContext(), LinearLayoutManager.VERTICAL));
        productsRecyclerView.setHasFixedSize(true);

        //Register the button and it's click listener
        Button nextButton = view.findViewById(R.id.next_button);

        nextButton.setOnClickListener(v -> {
            assert chooseProductAdapter != null;
            message.addProducts(chooseProductAdapter.getCheckedProducts());
            ChooseProductFragmentDirections.ActionChooseProductFragmentToLocationFragment action = ChooseProductFragmentDirections.actionChooseProductFragmentToLocationFragment();
            action.setMessage(message);
            Navigation.findNavController(v).navigate(action);

            Log.d(TAG, "onViewCreated: products count: " + chooseProductAdapter.getCheckedProducts().size());
        });

    }

    @Override
    public void onActivityCreated(@Nullable Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        ChooseProductViewModel mViewModel = new ViewModelProvider(this).get(ChooseProductViewModel.class);

        mViewModel.getProducts().observe(getViewLifecycleOwner(), products -> {

            chooseProductAdapter = new ChooseProductAdapter(products);
            productsRecyclerView.setAdapter(chooseProductAdapter);

        });
    }

}
<file_sep>package com.project.roadsideassistant.ui.fragments.profile;

import androidx.lifecycle.ViewModel;

public class SetupAccountViewModel extends ViewModel {
}
<file_sep>package com.project.roadsideassistant.ui;

import android.content.Intent;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;
import android.util.Patterns;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ProgressBar;
import android.widget.TextView;

import androidx.appcompat.app.AppCompatActivity;

import com.google.firebase.auth.FirebaseAuth;
import com.project.roadsideassistant.R;
import com.project.roadsideassistant.utils.UIHelpers;

public class RegisterActivity extends AppCompatActivity {

    private static final String TAG = "RegisterActivity";

    private FirebaseAuth mAuth;

    ProgressBar registerProgressBar;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_register);

        //Instantiating fire-base instance
        mAuth = FirebaseAuth.getInstance();

        EditText emailTxt = findViewById(R.id.email_txt);
        EditText passwordTxt = findViewById(R.id.password_txt);

        Button registerButton = findViewById(R.id.register_button);
        TextView gotoLoginTv = findViewById(R.id.goto_login_tv);

        registerProgressBar = findViewById(R.id.registerProgressBar);


        //Registration
        registerButton.setOnClickListener(v -> {

            String email = emailTxt.getText().toString().trim();
            String password = passwordTxt.getText().toString().trim();

            if (TextUtils.isEmpty(email)) {
                emailTxt.setError("Email is Required");
                emailTxt.requestFocus();
                return;
            }

            if (!Patterns.EMAIL_ADDRESS.matcher(email).matches()) {

                emailTxt.setError("Email is invalid");
                emailTxt.requestFocus();
                return;
            }

            if (password.length() < 6) {
                passwordTxt.setError("Password should be at least 6 characters");
                passwordTxt.requestFocus();
                return;
            }

            registerProgressBar.setVisibility(View.VISIBLE);
            registerUser(email, password);


        });

        gotoLoginTv.setOnClickListener(v -> finish());

    }

    @Override
    public void finish() {
        super.finish();
        overridePendingTransition(R.anim.slide_in_left, R.anim.slide_out_right);
    }

    private void registerUser(String email, String password) {
        mAuth.createUserWithEmailAndPassword(email, password)
                .addOnCompleteListener(task -> {
                    registerProgressBar.setVisibility(View.INVISIBLE);
                    if (task.isSuccessful()) {
                        Intent intent = new Intent(this, HomeActivity.class);
                        intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
                        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                        startActivity(intent);
                        overridePendingTransition(R.anim.slide_in_left, R.anim.slide_out_right);
                        finish();
                    } else {
                        assert task.getException() != null;

                        UIHelpers.toast("Registration failed: " + task.getException().getLocalizedMessage());
                        Log.e(TAG, "Authentication Failed: ", task.getException());
                    }
                });
    }
}
<file_sep>package com.project.roadsideassistant.data.repositories;

import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.firestore.FirebaseFirestore;

public class UserRepository {

    private FirebaseAuth mAuth;
    private FirebaseFirestore mDatabase;

    public UserRepository() {
        mAuth = FirebaseAuth.getInstance();
        mDatabase = FirebaseFirestore.getInstance();
    }

    public void getUserDetails(){

        assert mAuth.getCurrentUser() != null;


    }


    public interface UserTasksListener{

    }

}
<file_sep>package com.project.roadsideassistant.data.repositories;

import android.util.Log;

import com.google.firebase.firestore.FirebaseFirestore;
import com.project.roadsideassistant.data.models.Message;

public class MessageRepository {

    private FirebaseFirestore mDatabase;
    private MessageTaskListener listener;
    private static final String TAG = "MessageRepository";

    public MessageRepository(MessageTaskListener listener) {
        this.listener = listener;
        mDatabase = FirebaseFirestore.getInstance();
    }

    public void add(Message message) {
        mDatabase.collection("messages")
                .add(message)
                .addOnCompleteListener(task -> {

                    if (task.isSuccessful()) {
                        Log.d(TAG, "add: message added in repository");
                        listener.onComplete("Request Sent Successfully");

                    } else {
                        Log.e(TAG, "add: operation failed", task.getException());
                        listener.onError(task.getException());

                    }

                });
    }


    public interface MessageTaskListener {

        void onComplete(String message);

        void onError(Exception exception);
    }
}
