Skip to content

Commit

Permalink
chore: Add preference to force push data to Firebase server (#1089)
Browse files Browse the repository at this point in the history
Closes #1088
  • Loading branch information
barbeau authored Jun 14, 2022
1 parent 94a1036 commit b1529c1
Show file tree
Hide file tree
Showing 6 changed files with 148 additions and 1 deletion.
2 changes: 1 addition & 1 deletion onebusaway-android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -409,7 +409,7 @@ dependencies {
implementation 'com.google.firebase:firebase-analytics:21.0.0'
// Cloud Firestore (for storing destination alert test data)
implementation 'com.google.firebase:firebase-firestore:24.1.2'
implementation 'com.google.firebase:firebase-auth:21.0.3'
implementation 'com.google.firebase:firebase-auth:21.0.5'
implementation 'com.google.firebase:firebase-storage:20.0.1'
// Google Play Services Location (we need this on Amazon flavor too)
implementation 'com.google.android.gms:play-services-location:19.0.1'
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
/*
* Copyright (C) 2022 University of South Florida
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onebusaway.android.travelbehavior.io.coroutines

import android.app.ProgressDialog
import android.content.Context
import android.util.Log
import androidx.annotation.StringRes
import androidx.appcompat.app.AlertDialog
import com.google.firebase.firestore.FirebaseFirestore
import org.onebusaway.android.R
import org.onebusaway.android.app.Application
import org.onebusaway.android.travelbehavior.utils.TravelBehaviorUtils

const val TAG = "FirebaseDataPusher"

class FirebaseDataPusher {

/**
* Forces a push of data to the Firebase server. A dialog using [context] is shown while data
* is being pushed. A dialog using [context] with the result is shown after the attempt finishes.
*/
fun push(context: Context) {
if (!TravelBehaviorUtils.isUserParticipatingInStudy()) {
showUserNotEnrolledDialog(context)
Log.d(TAG, "User not enrolled in study - do nothing")
return
}
val waitDialog = ProgressDialog(context)
waitDialog.apply {
setTitle(R.string.push_firebase_data_dialog_title)
setMessage(Application.get().getString(R.string.push_firebase_data_dialog_summary))
setCancelable(false)
setCanceledOnTouchOutside(false)
setIndeterminate(true)
}

val db = FirebaseFirestore.getInstance()
db.enableNetwork() // This seems to be required to avoid an NPE in Firebase (forces internal check to ensureClientConfigured())
db.waitForPendingWrites().addOnCompleteListener {
Log.d(TAG, "Pushed to Firebase successfully")
waitDialog.hide()
showSuccessDialog(context)
}.addOnCanceledListener {
Log.e(TAG, "Push to Firebase canceled")
waitDialog.hide()
showCanceledDialog(context)
}.addOnFailureListener {
Log.e(TAG, "Push to Firebase failed")
waitDialog.hide()
showFailedDialog(context)
}
waitDialog.show()
}

private fun showUserNotEnrolledDialog(context: Context) {
showAlertDialog(
context,
R.string.push_firebase_data_dialog_user_not_enrolled_title,
R.string.push_firebase_data_dialog_user_not_enrolled_summary
)
}

private fun showSuccessDialog(context: Context) {
showAlertDialog(
context,
R.string.push_firebase_data_dialog_success_title,
R.string.push_firebase_data_dialog_success_summary
)
}

private fun showFailedDialog(context: Context) {
showAlertDialog(
context,
R.string.push_firebase_data_dialog_failed_title,
R.string.push_firebase_data_dialog_failed_summary
)
}

private fun showCanceledDialog(context: Context) {
showAlertDialog(
context,
R.string.push_firebase_data_dialog_canceled_title,
R.string.push_firebase_data_dialog_canceled_summary
)
}

private fun showAlertDialog(context: Context, @StringRes title: Int, @StringRes summary: Int) {
val dialog = AlertDialog.Builder(context)
dialog.apply {
setTitle(title)
setMessage(
Application.get()
.getString(summary)
)
setPositiveButton(R.string.ok) { _, _ -> }
}
dialog.show()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@
import org.onebusaway.android.provider.ObaContract;
import org.onebusaway.android.region.ObaRegionsTask;
import org.onebusaway.android.travelbehavior.TravelBehaviorManager;
import org.onebusaway.android.travelbehavior.io.coroutines.FirebaseDataPusher;
import org.onebusaway.android.travelbehavior.utils.TravelBehaviorUtils;
import org.onebusaway.android.util.BackupUtils;
import org.onebusaway.android.util.BuildFlavorUtils;
Expand Down Expand Up @@ -107,6 +108,8 @@ public class PreferencesActivity extends PreferenceActivity

Preference mRestoreBackup;

Preference pushFirebaseData;

boolean mAutoSelectInitialValue;

boolean mOtpCustomAPIUrlChanged = false;
Expand Down Expand Up @@ -160,6 +163,9 @@ public void onCreate(Bundle savedInstanceState) {
mTravelBehaviorPref.setChecked(TravelBehaviorUtils.isUserParticipatingInStudy());
}

pushFirebaseData = findPreference(getString(R.string.preference_key_push_firebase_data));
pushFirebaseData.setOnPreferenceClickListener(this);

mHideAlertsPref = findPreference(getString(R.string.preference_key_hide_alerts));
mHideAlertsPref.setOnPreferenceChangeListener(this);

Expand Down Expand Up @@ -344,6 +350,10 @@ public boolean onPreferenceClick(Preference pref) {
// RestorePreference will get the click event but will ignore it if permissions haven't
// been granted yet so we can handle permissions here.
maybeRequestPermissions(RESTORE_BACKUP_PERMISSION_REQUEST);
} else if (pref.equals(pushFirebaseData)) {
// Try to push firebase data to the server
FirebaseDataPusher pusher = new FirebaseDataPusher();
pusher.push(this);
}
return true;
}
Expand Down
1 change: 1 addition & 0 deletions onebusaway-android/src/main/res/values/donottranslate.xml
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@
<string name="preference_key_never_show_destination_reminder_beta_dialog">preference_never_show_destination_reminder_beta_dialog</string>
<string name="preferences_key_travel_behavior">preference_travel_behavior</string>
<string name="preferences_key_user_denied_location_permissions">preferences_key_user_denied_location_permissions</string>
<string name="preference_key_push_firebase_data">preference_key_push_firebase_data</string>

<!-- Regions API URL -->
<string name="regions_api_url">https://regions.onebusaway.org/regions-v3.json</string>
Expand Down
19 changes: 19 additions & 0 deletions onebusaway-android/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -702,6 +702,25 @@
<string name="preferences_powered_by_oba_title">Powered by OneBusAway</string>
<string name="preferences_powered_by_oba_summary">Find out more about the open-source project
</string>

<string name="preferences_push_firebase_data_title">Push Firebase data to server</string>
<string name="preferences_push_firebase_data_summary">If you\'ve opted into a travel behavior study, tapping this option will trigger a push of collected travel behavior data to the Firebase server. This is useful while testing the app and is intended for use by developers. For best results make sure you have a strong Internet connection first.</string>

<string name="push_firebase_data_dialog_title">Pushing Firebase data…</string>
<string name="push_firebase_data_dialog_summary">Waiting until all currently pending writes for the active user have been acknowledged by the backend…</string>

<string name="push_firebase_data_dialog_user_not_enrolled_title">User not enrolled</string>
<string name="push_firebase_data_dialog_user_not_enrolled_summary">Push to Firebase was not attempted as user is not enrolled in travel behavior data collection. You can enroll by enabling the Setting for \"Send anonymous travel behavior data\".</string>

<string name="push_firebase_data_dialog_success_title">Push successful</string>
<string name="push_firebase_data_dialog_success_summary">All currently pending writes for the active user have been acknowledged by the Firebase backend.</string>

<string name="push_firebase_data_dialog_failed_title">Push failed</string>
<string name="push_firebase_data_dialog_failed_summary">Something went wrong. Please make sure you have a strong Internet connection and try again.</string>

<string name="push_firebase_data_dialog_canceled_title">Push canceled</string>
<string name="push_firebase_data_dialog_canceled_summary">Something went wrong. Please make sure you have a strong Internet connection and try again.</string>

<string name="preferences_about_title">About</string>
<string name="preferences_about_summary">Version, contributor, and license information</string>
<!-- Units -->
Expand Down
4 changes: 4 additions & 0 deletions onebusaway-android/src/main/res/xml/preferences.xml
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,10 @@
android:key="@string/preference_key_otp_api_url"
android:summary="@string/preferences_otp_api_servername_summary"
android:title="@string/preferences_otp_api_servername_title" />
<Preference
android:key="@string/preference_key_push_firebase_data"
android:title="@string/preferences_push_firebase_data_title"
android:summary="@string/preferences_push_firebase_data_summary"/>
</PreferenceCategory>
</PreferenceScreen>
</PreferenceCategory>
Expand Down

0 comments on commit b1529c1

Please sign in to comment.