diff --git a/README.md b/README.md
index 68cfe2e..85411ea 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,32 @@
-# MaizeBus
+
+
+# Quickstart (Recommended)
+## Create an API key for Google Maps
+**Keep your API key secret!** Your Google Maps API key is just for your local build of Maizebus (we'll use a different one when publishing to the app store). Our GitHub repository is configured to ignore `android/local.properties` and `ios/Flutter/gmap.xcconfig` so you're safe to commit as usual.
+
+You have two options for getting your API key: either use a Maps Demo Key or get an API key through Google Cloud. The Maps Demo key doesn't require a credit card but is newer and might have stricter usage limits. Google Cloud requires you to have a credit card on file, but our usage stays in the free tier (we're using the "Maps SDK", which has [unlimited free usage](https://developers.google.com/maps/billing-and-pricing/pricing#map-loads-pricing)). I would recommend getting your API key from Google Cloud since it's more stable.
+
+1. Option A: Use a Maps Demo Key (no credit card required)
+ 1. Visit the [Maps Demo Key page](https://mapsplatform.google.com/maps-demo-key/?utm_experiment=13103221)
+ 2. Click "Try for free" and sign in with your Google Account
+ 3. Agree to the terms, and you should see your Maps Demo Key!
+2. Option B: Create an API key through Google Cloud
+ 1. Open the [Google Cloud Console](https://console.cloud.google.com/google/maps-apis/overview). Create an account if you don't already have one
+ 2. In the toolbar you should see the Project Picker (right next to "Google Cloud"). Click it and create a new project. Call it whatever you like (such as "Local-Maizebus-Testing")
+ 3. In the sidebar, click "APIs & Services" and enable "Maps SDK for Android" and "Maps SDK for iOS"
+ 4. Now click on "Keys & Credentials" in the sidebar
+ 5. Click on the "Maps Platform API Key" under "API Keys", then click "Show key"
+
+## Run automatic setup
+1. Make sure Flutter is installed on your computer (see [this guide](https://docs.flutter.dev/install) for how to do this)
+2. Open a terminal (Mac) or WSL terminal (Windows) in the project folder. Run `./setup.sh` to start the setup process
+3. Paste your Google Maps API key into the setup script when prompted. The setup script will add your API key to the project
+4. Launch an emulator and click the green Run button in VSCode to build and run the project! Alternatively you can run `flutter run` in your terminal
+
+**Note:** `setup.sh` disables Firebase by default and creates dummy configuration files. Most frontend developers probably won't work on the notification system, so we're saving you all the pain of having to get a Firebase API key and configure flutterfire. If you'd like to configure Firebase properly, see the section below.
+
+
+# Manual Setup
## Google Maps Setup (iOS)
diff --git a/lib/services/notification_service.dart b/lib/services/notification_service.dart
index 45a8ab9..30d0a32 100644
--- a/lib/services/notification_service.dart
+++ b/lib/services/notification_service.dart
@@ -8,6 +8,7 @@ import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
+const useFirebase = bool.fromEnvironment('USE_FIREBASE', defaultValue: kReleaseMode);
class NotificationService {
static final _localNotificationsPlugin = FlutterLocalNotificationsPlugin();
static bool _listeningForFcmUpdates = false;
@@ -22,10 +23,12 @@ class NotificationService {
/// e.g. call it asap if notifications were previously used, otherwise wait for
/// the user to trigger a feature that requires notifications
static Future initPlugin() async {
- await Firebase.initializeApp(
- name: "[DEFAULT]",
- options: DefaultFirebaseOptions.currentPlatform,
- );
+ if (useFirebase) {
+ await Firebase.initializeApp(
+ name: "[DEFAULT]",
+ options: DefaultFirebaseOptions.currentPlatform,
+ );
+ }
// prepare local notifications
const AndroidInitializationSettings androidSettings =
@@ -69,6 +72,8 @@ class NotificationService {
// Currently this function must be called even if permission is already granted,
// as it sets up some important listeners
static Future requestPermission() async {
+ if (!useFirebase) return; // If Firebase is disabled for development skip all this
+
// todo: add back in if needed
final notificationSettings = await FirebaseMessaging.instance
.requestPermission();
diff --git a/setup.sh b/setup.sh
new file mode 100755
index 0000000..a76fcf1
--- /dev/null
+++ b/setup.sh
@@ -0,0 +1,118 @@
+#!/bin/bash
+set -Eeuo pipefail
+
+BLACK="\e[30m";
+RED="\033[31m";
+GREEN="\033[32m";
+YELLOW="\033[33m";
+BLUE="\033[34m";
+MAGENTA="\033[35m";
+CYAN="\033[36m";
+WHITE="\033[37m";
+RESET="\033[0m";
+
+if flutter --version; then
+ echo "Found Flutter installation!"
+else
+ echo "Error: Could not find Flutter"
+ exit 1
+fi
+
+flutter doctor
+
+echo "Please paste in your Google Maps API key: "
+
+read gmaps_apikey
+
+touch ios/Flutter/gmap.xcconfig
+sed -E 's/^GMapApiKey=([A-Za-z0-9]+)//' ios/Flutter/gmap.xcconfig # Remove all old API keys from gmap.xcconfig
+echo "GMapApiKey=$gmaps_apikey" > ios/Flutter/gmap.xcconfig # Add API key to gmap.xcconfig
+touch android/local.properties
+grep -v '^GOOGLE_MAPS_API_KEY=' android/local.properties > android/local.properties.tmp || true # Remove all old API keys from local.properties
+mv android/local.properties.tmp android/local.properties
+printf "\nGOOGLE_MAPS_API_KEY=$gmaps_apikey" >> android/local.properties # Add API key to local.properties
+
+flutter pub get
+
+if [ ! -f lib/firebase_options.dart ]; then
+touch lib/firebase_options.dart
+> lib/firebase_options.dart # Clear the file
+cat > lib/firebase_options.dart << 'EOF'
+// Dummy Firebase config file. WILL NOT CONNECT TO FIREBASE OR RECEIVE NOTIFICATIONS
+// To set the app up to use Firebase notifications, follow this tutorial: https://firebase.google.com/docs/flutter/setup
+// ignore_for_file: type=lint
+import 'package:firebase_core/firebase_core.dart' show FirebaseOptions;
+import 'package:flutter/foundation.dart'
+ show defaultTargetPlatform, kIsWeb, TargetPlatform;
+
+// If you're seeing a compile error here, you're making a release build with the
+// dummy Firebase config. Set up the real one: https://firebase.google.com/docs/flutter/setup
+// ignore: unused_element
+const _noReleaseWithDummyFirebase = 1 ~/ (bool.fromEnvironment('dart.vm.product') ? 0 : 1);
+
+
+/// Default [FirebaseOptions] for use with your Firebase apps.
+///
+/// Example:
+/// ```dart
+/// import 'firebase_options.dart';
+/// // ...
+/// await Firebase.initializeApp(
+/// options: DefaultFirebaseOptions.currentPlatform,
+/// );
+/// ```
+class DefaultFirebaseOptions {
+ static FirebaseOptions get currentPlatform {
+ throw UnsupportedError("Firebase hasn't been configured for this project! Please delete firebase_options.dart and follow the tutorial at https://firebase.google.com/docs/flutter/setup");
+ }
+
+ static const FirebaseOptions android = FirebaseOptions(
+ apiKey: 'dummy-api-key',
+ appId: 'dummy-app-id',
+ messagingSenderId: 'dummy-sender-id',
+ projectId: 'dummy-project-id',
+ storageBucket: 'dummy-project-id.appspot.com',
+ );
+}
+EOF
+else
+ printf "${YELLOW}Note: lib/firebase_options.dart already exists and was not overwritten $RESET\n"
+ printf " If you'd like to replace firebase_options.dart with the dummy version,\n"
+ printf " remove it and run this script again\n"
+fi
+
+if [ ! -f android/app/google-services.json ]; then
+cat > android/app/google-services.json << 'EOF'
+{
+"project_info": {
+ "project_number": "000000000000",
+ "project_id": "dummy-project-id",
+ "storage_bucket": "dummy-project-id.appspot.com"
+},
+"client": [
+ {
+ "client_info": {
+ "mobilesdk_app_id": "1:000000000000:android:0000000000000000000000",
+ "android_client_info": {
+ "package_name": "com.ishankumar.maizebus"
+ }
+ },
+ "oauth_client": [],
+ "api_key": [{ "current_key": "dummy-api-key" }],
+ "services": { "appinvite_service": { "other_platform_oauth_client": [] } }
+ }
+],
+"configuration_version": "1"
+}
+EOF
+else
+ printf "${YELLOW}Note: android/app/google-services.json already exists and was not overwritten$RESET\n"
+ printf " If you'd like to replace google-services.json with the dummy version,\n"
+ printf " remove it and run this script again\n"
+fi
+
+# npm i -g firebase-tools # Install Firebase tools
+
+
+# dart pub global activate flutterfire_cli
+