bgabriel998/SoftwareDevProject

View on GitHub
app/src/main/java/ch/epfl/sdp/peakar/database/Database.java

Summary

Maintainability
A
0 mins
Test Coverage
B
85%
package ch.epfl.sdp.peakar.database;

import android.content.Context;
import android.content.SharedPreferences;
import android.util.Log;

import androidx.preference.PreferenceManager;

import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseError;
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.database.ValueEventListener;

import java.util.concurrent.atomic.AtomicBoolean;

import ch.epfl.sdp.peakar.R;
import ch.epfl.sdp.peakar.database.providers.firebase.FirebaseDatabaseReference;

import static ch.epfl.sdp.peakar.database.providers.firebase.FirebaseDatabaseReference.DATABASE_ADDRESS;

/**
 * This class represents a Database.
 * It implements the singleton pattern so only one Database object can exist.
 */
public class Database {
    /* CHILD PATH CONSTANTS */
    public static final String CHILD_USERS = "users/";
    public static final String CHILD_FRIENDS = "friends/";
    public static final String CHILD_PHOTO_URL = "photo";
    public static final String CHILD_DISCOVERED_PEAKS = "DiscoveredPeaks";
    public static final String CHILD_DISCOVERED_PEAKS_HEIGHTS = "DiscoveredHeights";
    public static final String CHILD_USERNAME = "username";
    public static final String CHILD_SCORE = "score";
    public static final String CHILD_COUNTRY_HIGH_POINT = "CountryHighPoint";
    public static final String CHILD_COUNTRY_HIGH_POINT_NAME = "countryHighPoint";
    public static final String CHILD_ATTRIBUTE_HIGH_POINT_HEIGHT = "highPointHeight";
    public static final String CHILD_ATTRIBUTE_COUNTRY_NAME = "countryName";
    public static final String CHILD_ATTRIBUTE_PEAK_NAME = "name";
    public static final String CHILD_ATTRIBUTE_PEAK_LATITUDE = "latitude";
    public static final String CHILD_ATTRIBUTE_PEAK_LONGITUDE = "longitude";
    public static final String CHILD_ATTRIBUTE_PEAK_ALTITUDE = "altitude";
    public static final String CHILD_ATTRIBUTE_PEAK_DISCOVERED_DATE = "discoveredDate";
    public static final String CHILD_CHALLENGES = "challenges/";
    public static final String CHILD_CHALLENGE_NAME = "name";
    public static final String CHILD_CHALLENGE_STATUS = "challengeStatus";
    public static final String CHILD_CHALLENGE_START = "startTimeAndDate";
    public static final String CHILD_CHALLENGE_CREATION = "creationTimeAndDate";
    public static final String CHILD_CHALLENGE_FINISH = "finishTimeAndDate";
    public static final String CHILD_CHALLENGE_DURATION = "durationInDays";
    public static final String CHILD_CHALLENGE_FOUNDER = "founder";

    /* SINGLETON ATTRIBUTES */
    private static Database instance;
    private final DatabaseReference reference;
    private final AtomicBoolean online = new AtomicBoolean(false);

    private Database() {
        // Enable persistence
        FirebaseDatabase.getInstance(DATABASE_ADDRESS).setPersistenceEnabled(true);
        reference = new FirebaseDatabaseReference();
        // Start connection listener, that will automatically set the online var to false whenever the db is not connected and viceversa
        FirebaseDatabase.getInstance(DATABASE_ADDRESS).getReference(".info/connected").addValueEventListener(new ValueEventListener() {
            @Override
            public void onDataChange(DataSnapshot snapshot) {
                boolean connected = snapshot.getValue(Boolean.class);
                online.set(connected);
                Log.d("Database", "connected = " + connected);
            }

            @Override
            public void onCancelled(DatabaseError error) {
                online.set(false);
                Log.d("Database", "onCancelled: error");
            }
        });
    }

    /**
     * Get a database instance.
     */
    public static Database getInstance() {
        if(instance == null) instance = new Database();
        return instance;
    }

    /**
     * Init method for the database. Handle the offline mode settings and enables persistence.
     *
     * IMPORTANT: this method <b>MUST</b> be called in the <code>InitActivity</code> before other calls to the <code>Database</code> class are performed.
     *
     * @param context context of the application.
     */
    public static void init(Context context) {
        // Check that if offline mode is active, and in this case call the right method
        SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
        boolean offlineModeValue = prefs.getBoolean(context.getResources().getString(R.string.offline_mode_key), false);

        Database instance = getInstance();

        if (offlineModeValue) {
            instance.setOfflineMode();
        }
    }

    /**
     * Get a reference to the root of the database.
     */
    public DatabaseReference getReference() {
        return reference;
    }

    /**
     * Enable the DB offline mode.
     * Requests for which data is cached can still be answered.
     * Other requests will be enqueued until online mode is set.
     */
    public void setOfflineMode() {
        FirebaseDatabase.getInstance(DATABASE_ADDRESS).goOffline();
    }

    /**
     * Enable the DB online mode.
     */
    public void setOnlineMode() {
        FirebaseDatabase.getInstance(DATABASE_ADDRESS).goOnline();
    }

    /**
     * Check if the DB connection is up.
     *
     * @return true if DB connection is up, false otherwise.
     */
    public boolean isOnline() {
        return online.get();
    }
}