movemeet/movemeet

View on GitHub
app/src/main/java/com/sdp/movemeet/utility/ActivitiesUpdater.java

Summary

Maintainability
A
0 mins
Test Coverage
B
89%
package com.sdp.movemeet.utility;

import android.util.Log;

import androidx.annotation.VisibleForTesting;

import com.google.android.gms.tasks.OnCompleteListener;
import com.google.android.gms.tasks.Task;
import com.google.firebase.firestore.DocumentSnapshot;
import com.google.firebase.firestore.EventListener;
import com.google.firebase.firestore.QuerySnapshot;
import com.sdp.movemeet.backend.firebase.firestore.FirestoreActivityManager;
import com.sdp.movemeet.backend.serialization.ActivitySerializer;
import com.sdp.movemeet.backend.serialization.BackendSerializer;
import com.sdp.movemeet.models.Activity;

import java.util.ArrayList;

/**
 * This utility class is used to fetch the activities from the database into local
 */
public abstract class ActivitiesUpdater {

    public static final BackendSerializer<Activity> serializer = new ActivitySerializer();

    @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
    public static ArrayList<Activity> activities = new ArrayList<>();
    private static final FirestoreActivityManager firestoreActivityManager = new FirestoreActivityManager(FirestoreActivityManager.ACTIVITIES_COLLECTION, serializer);

    private static final String TAG = "Activities updater TAG";

    /**
     * Method that returns the local list of activities (empty by default). We first have to update the list before getting it, to
     * make sure that we always have all the activities from the database in the local list
     *
     * @return local list of activities
     */
    public static ArrayList<Activity> getActivities() {
        return activities;
    }

    /**
     * Updates the local list of activities, by retrieving only newly added activities in db collection. When complete, something
     * should happen (use onCompleteListener). If an activity is changed in the db, this change should also happen in local (use eventListener)
     *
     * @param onCompletelistener used as a callback when the activities are fetched from db
     * @param eventListener      used as a callback when an activitiy is updated in the db
     */
    public static void updateListActivities(OnCompleteListener onCompletelistener, EventListener<DocumentSnapshot> eventListener) {
        if (onCompletelistener == null || eventListener == null) {
            Log.d(TAG, "listeners shouldn't be null");
            return;
        }
        Task<QuerySnapshot> allDocTask = firestoreActivityManager.getAll();
        //Count the number of elements in the collection
        allDocTask.addOnSuccessListener(queryDocumentSnapshots -> {
            // Calculate the number of newly added activities in the collection
            int size = queryDocumentSnapshots.getDocuments().size() - activities.size();
            //In case there is more activities in local than db (e.g if activities were deleted from db), than we clear the list and refetch
            if (size < 0) {
                clearLocalActivities();
                updateListActivities(onCompletelistener, eventListener);
                return;
            } else if (size == 0) allDocTask.addOnCompleteListener(onCompletelistener);
                //Either way, when updating the list, we update the map as well
            else
                addActivitiesOnSuccess(firestoreActivityManager.getRecentlyAddedActivities(size), eventListener).addOnCompleteListener(onCompletelistener);
        });
    }

    /**
     * On success, add the activities from db to the local list of activities
     *
     * @param task task containing the requested snapshots, that would then be deserialized into activities
     */
    private static Task addActivitiesOnSuccess(Task<QuerySnapshot> task, EventListener<DocumentSnapshot> eventListener) {
        return task.addOnSuccessListener(queryDocumentSnapshots -> {
            for (DocumentSnapshot docSnap : queryDocumentSnapshots.getDocuments()) {
                Activity act = serializer.deserialize(docSnap.getData());
                activities.add(act);
                //for the given activity, we make sure that it will always be updated on map
                firestoreActivityManager.setActivitiesUpdateListener(act, eventListener);
            }
        }).addOnFailureListener(e -> Log.d(TAG, e.toString()));
    }

    /**
     * Clear the local list of activities
     */
    public static void clearLocalActivities() {
        activities.clear();
    }
}