diff --git a/.gitignore b/.gitignore index fe5a088..37b7f72 100644 --- a/.gitignore +++ b/.gitignore @@ -286,4 +286,6 @@ fabric.properties # Custom rules (everything added below won't be overriden by 'Generate .gitignore File' if you use 'Update' option) -.vscode \ No newline at end of file +.vscode +*/**/.env +frontend/web/firebaseConfig.js \ No newline at end of file diff --git a/backend/functions/package-lock.json b/backend/functions/package-lock.json index d56789c..1a01948 100644 --- a/backend/functions/package-lock.json +++ b/backend/functions/package-lock.json @@ -4,7 +4,6 @@ "requires": true, "packages": { "": { - "name": "functions", "dependencies": { "firebase-admin": "^9.8.0", "firebase-functions": "^3.14.1" diff --git a/backend/functions/src/index.ts b/backend/functions/src/index.ts index 1d51717..853a28f 100644 --- a/backend/functions/src/index.ts +++ b/backend/functions/src/index.ts @@ -1,6 +1,6 @@ import * as functions from "firebase-functions"; import * as admin from "firebase-admin"; -import {TaskType, TaskTypeWithID} from "./types"; +import { TaskType, TaskTypeWithID } from "./types"; admin.initializeApp(); admin.firestore().settings({ ignoreUndefinedProperties: true, @@ -10,7 +10,7 @@ admin.firestore().settings({ // https://firebase.google.com/docs/functions/typescript // export const helloWorld = functions.https.onRequest((request, response) => { - functions.logger.info("Hello logs!", {structuredData: true}); + functions.logger.info("Hello logs!", { structuredData: true }); response.send("Hello from Firebase!"); }); @@ -21,15 +21,8 @@ export const helloWorld = functions.https.onRequest((request, response) => { */ const getTaskFromRequest = (request: functions.Request): TaskType => { - const { - title, - description, - dueDate, - priority, - groupId, - creator, - createdAt, - } = request.body; + const { title, description, dueDate, priority, groupId, creator, createdAt } = + request.body; const task: TaskType = { title, creator, @@ -41,104 +34,100 @@ const getTaskFromRequest = (request: functions.Request): TaskType => { }; return task; }; -export const createTask = functions.https - .onRequest(async (request, response) => { - const task = {...getTaskFromRequest(request), - createdAt: new Date().toISOString(), - }; +export const createTask = functions.https.onRequest( + async (request, response) => { + const task = { + ...getTaskFromRequest(request), + createdAt: new Date().toISOString(), + }; - if (!task.title || !task.creator) { - response.status(400).send("Title is required."); - return; - } + if (!task.title || !task.creator) { + response.status(400).send("Title is required."); + return; + } - try { - const ref = await admin.firestore().collection("tasks").add(task); - response.send(ref.id); - } catch (e) { - response.status(500).send(e); - } - }); + try { + const ref = await admin.firestore().collection("tasks").add(task); + response.send(ref.id); + } catch (e) { + response.status(500).send(e); + } + } +); /** * On Success: Returns a Task. * On Failure: Returns 400 Response (Bad Request). */ -export const getTask = functions.https - .onRequest(async (request, response) => { - const id = request.query.id as string; - if (!id || typeof id !== "string") { - response.status(400).send("ID is required."); - return; - } - try { - const ref = await admin.firestore().collection("tasks").doc(id).get(); - response.send(ref.data()); - } catch (e) { - response.status(500).send(e); - } - } - ); +export const getTask = functions.https.onRequest(async (request, response) => { + const id = request.query.id as string; + if (!id || typeof id !== "string") { + response.status(400).send("ID is required."); + return; + } + try { + const ref = await admin.firestore().collection("tasks").doc(id).get(); + response.send(ref.data()); + } catch (e) { + response.status(500).send(e); + } +}); /** * On Success: Returns all Tasks. * On Failure: Returns 400 Response (Bad Request). */ -export const listTasks = functions.https - .onRequest(async (request, response) => { - try { - const ref = await admin.firestore().collection("tasks").get(); - const tasks: TaskTypeWithID[] = []; - ref.forEach((doc) => { - tasks.push({...doc.data(), id: doc.id} as TaskTypeWithID); - }); - response.send(tasks); - } catch (e) { - response.status(500).send(e); - } +export const listTasks = functions.https.onRequest( + async (request, response) => { + try { + const ref = await admin.firestore().collection("tasks").get(); + const tasks: TaskTypeWithID[] = []; + ref.forEach((doc) => { + tasks.push({ ...doc.data(), id: doc.id } as TaskTypeWithID); + }); + response.send(tasks); + } catch (e) { + response.status(500).send(e); } - ); + } +); -export const updateTask = functions.https - .onRequest(async (request, response) => { - const id = request.query.id as string; - if (!id || typeof id !== "string") { - response.status(400).send("ID is required."); - return; - } - const task = getTaskFromRequest(request); - try { - const ref = await admin.firestore().collection("tasks").doc(id); - const exists = await (await ref.get()).exists; - if (!exists) { - response.status(404).send("Task not found."); - return; - } - await ref.update( - task - ); - response.send("ok"); - } catch (e) { - response.status(500).send(e); - } +export const updateTask = functions.https.onRequest( + async (request, response) => { + const id = request.query.id as string; + if (!id || typeof id !== "string") { + response.status(400).send("ID is required."); + return; } - ); - -export const deleteTask = functions.https - .onRequest(async (request, response) => { - const id = request.query.id as string; - if (!id || typeof id !== "string") { - response.status(400).send("ID is required."); + const task = getTaskFromRequest(request); + try { + const ref = await admin.firestore().collection("tasks").doc(id); + const exists = await (await ref.get()).exists; + if (!exists) { + response.status(404).send("Task not found."); return; } - try { - const ref = await admin.firestore().collection("tasks").doc(id); - await ref.delete(); - response.send("ok"); - } catch (e) { - response.status(500).send(e); - } + await ref.update(task); + response.send("ok"); + } catch (e) { + response.status(500).send(e); } - ); - + } +); +export const deleteTask = functions.https.onRequest( + async (request, response) => { + const id = request.query.id as string; + if (!id || typeof id !== "string") { + response.status(400).send("ID is required."); + return; + } + try { + const ref = await admin.firestore().collection("tasks").doc(id); + await ref.delete(); + response.send("ok"); + } catch (e) { + response.status(500).send(e); + } + } +); diff --git a/frontend/ios/Podfile.lock b/frontend/ios/Podfile.lock index 22f59a4..ebd5a1e 100644 --- a/frontend/ios/Podfile.lock +++ b/frontend/ios/Podfile.lock @@ -83,8 +83,45 @@ PODS: - abseil/base/throw_delegate (0.20200225.0): - abseil/base/config - abseil/base/raw_logging_internal + - abseil/container/common (0.20200225.0): + - abseil/meta/type_traits + - abseil/types/optional - abseil/container/compressed_tuple (0.20200225.0): - abseil/utility/utility + - abseil/container/container_memory (0.20200225.0): + - abseil/memory/memory + - abseil/utility/utility + - abseil/container/fixed_array (0.20200225.0): + - abseil/algorithm/algorithm + - abseil/base/core_headers + - abseil/base/dynamic_annotations + - abseil/base/throw_delegate + - abseil/container/compressed_tuple + - abseil/memory/memory + - abseil/container/flat_hash_map (0.20200225.0): + - abseil/algorithm/container + - abseil/container/container_memory + - abseil/container/hash_function_defaults + - abseil/container/raw_hash_map + - abseil/memory/memory + - abseil/container/hash_function_defaults (0.20200225.0): + - abseil/base/config + - abseil/hash/hash + - abseil/strings/strings + - abseil/container/hash_policy_traits (0.20200225.0): + - abseil/meta/type_traits + - abseil/container/hashtable_debug_hooks (0.20200225.0): + - abseil/base/config + - abseil/container/hashtablez_sampler (0.20200225.0): + - abseil/base/base + - abseil/base/core_headers + - abseil/base/exponential_biased + - abseil/container/have_sse + - abseil/debugging/stacktrace + - abseil/memory/memory + - abseil/synchronization/synchronization + - abseil/utility/utility + - abseil/container/have_sse (0.20200225.0) - abseil/container/inlined_vector (0.20200225.0): - abseil/algorithm/algorithm - abseil/base/core_headers @@ -97,6 +134,70 @@ PODS: - abseil/memory/memory - abseil/meta/type_traits - abseil/types/span + - abseil/container/layout (0.20200225.0): + - abseil/base/core_headers + - abseil/meta/type_traits + - abseil/strings/strings + - abseil/types/span + - abseil/utility/utility + - abseil/container/raw_hash_map (0.20200225.0): + - abseil/base/throw_delegate + - abseil/container/container_memory + - abseil/container/raw_hash_set + - abseil/container/raw_hash_set (0.20200225.0): + - abseil/base/bits + - abseil/base/config + - abseil/base/core_headers + - abseil/base/endian + - abseil/container/common + - abseil/container/compressed_tuple + - abseil/container/container_memory + - abseil/container/hash_policy_traits + - abseil/container/hashtable_debug_hooks + - abseil/container/hashtablez_sampler + - abseil/container/have_sse + - abseil/container/layout + - abseil/memory/memory + - abseil/meta/type_traits + - abseil/utility/utility + - abseil/debugging/debugging_internal (0.20200225.0): + - abseil/base/config + - abseil/base/core_headers + - abseil/base/dynamic_annotations + - abseil/base/errno_saver + - abseil/base/raw_logging_internal + - abseil/debugging/demangle_internal (0.20200225.0): + - abseil/base/base + - abseil/base/config + - abseil/base/core_headers + - abseil/debugging/stacktrace (0.20200225.0): + - abseil/base/config + - abseil/base/core_headers + - abseil/debugging/debugging_internal + - abseil/debugging/symbolize (0.20200225.0): + - abseil/base/base + - abseil/base/config + - abseil/base/core_headers + - abseil/base/dynamic_annotations + - abseil/base/malloc_internal + - abseil/base/raw_logging_internal + - abseil/debugging/debugging_internal + - abseil/debugging/demangle_internal + - abseil/hash/city (0.20200225.0): + - abseil/base/config + - abseil/base/core_headers + - abseil/base/endian + - abseil/hash/hash (0.20200225.0): + - abseil/base/core_headers + - abseil/base/endian + - abseil/container/fixed_array + - abseil/hash/city + - abseil/meta/type_traits + - abseil/numeric/int128 + - abseil/strings/strings + - abseil/types/optional + - abseil/types/variant + - abseil/utility/utility - abseil/memory (0.20200225.0): - abseil/memory/memory (= 0.20200225.0) - abseil/memory/memory (0.20200225.0): @@ -136,6 +237,31 @@ PODS: - abseil/meta/type_traits - abseil/numeric/int128 - abseil/strings/internal + - abseil/synchronization/graphcycles_internal (0.20200225.0): + - abseil/base/base + - abseil/base/base_internal + - abseil/base/config + - abseil/base/core_headers + - abseil/base/malloc_internal + - abseil/base/raw_logging_internal + - abseil/synchronization/kernel_timeout_internal (0.20200225.0): + - abseil/base/core_headers + - abseil/base/raw_logging_internal + - abseil/time/time + - abseil/synchronization/synchronization (0.20200225.0): + - abseil/base/atomic_hook + - abseil/base/base + - abseil/base/base_internal + - abseil/base/config + - abseil/base/core_headers + - abseil/base/dynamic_annotations + - abseil/base/malloc_internal + - abseil/base/raw_logging_internal + - abseil/debugging/stacktrace + - abseil/debugging/symbolize + - abseil/synchronization/graphcycles_internal + - abseil/synchronization/kernel_timeout_internal + - abseil/time/time - abseil/time (0.20200225.0): - abseil/time/internal (= 0.20200225.0) - abseil/time/time (= 0.20200225.0) @@ -218,42 +344,45 @@ PODS: - BoringSSL-GRPC/Implementation (0.0.7): - BoringSSL-GRPC/Interface (= 0.0.7) - BoringSSL-GRPC/Interface (0.0.7) - - cloud_firestore (0.16.0-1): - - Firebase/Firestore (= 7.3.0) + - cloud_firestore (3.1.0): + - Firebase/Firestore (= 8.9.0) - firebase_core - Flutter - - Firebase/CoreOnly (7.3.0): - - FirebaseCore (= 7.3.0) - - Firebase/Firestore (7.3.0): + - Firebase/CoreOnly (8.9.0): + - FirebaseCore (= 8.9.0) + - Firebase/Firestore (8.9.0): - Firebase/CoreOnly - - FirebaseFirestore (~> 7.3.0) - - firebase_core (0.7.0): - - Firebase/CoreOnly (= 7.3.0) + - FirebaseFirestore (~> 8.9.0) + - firebase_core (1.10.0): + - Firebase/CoreOnly (= 8.9.0) - Flutter - - FirebaseCore (7.3.0): - - FirebaseCoreDiagnostics (~> 7.0) - - GoogleUtilities/Environment (~> 7.0) - - GoogleUtilities/Logger (~> 7.0) - - FirebaseCoreDiagnostics (7.3.0): - - GoogleDataTransport (~> 8.0) - - GoogleUtilities/Environment (~> 7.0) - - GoogleUtilities/Logger (~> 7.0) - - nanopb (~> 2.30906.0) - - FirebaseFirestore (7.3.0): + - FirebaseCore (8.9.0): + - FirebaseCoreDiagnostics (~> 8.0) + - GoogleUtilities/Environment (~> 7.6) + - GoogleUtilities/Logger (~> 7.6) + - FirebaseCoreDiagnostics (8.10.0): + - GoogleDataTransport (~> 9.1) + - GoogleUtilities/Environment (~> 7.6) + - GoogleUtilities/Logger (~> 7.6) + - nanopb (~> 2.30908.0) + - FirebaseFirestore (8.9.1): - abseil/algorithm (= 0.20200225.0) - abseil/base (= 0.20200225.0) + - abseil/container/flat_hash_map (= 0.20200225.0) - abseil/memory (= 0.20200225.0) - abseil/meta (= 0.20200225.0) - abseil/strings/strings (= 0.20200225.0) - abseil/time (= 0.20200225.0) - abseil/types (= 0.20200225.0) - - FirebaseCore (~> 7.0) + - FirebaseCore (~> 8.0) - "gRPC-C++ (~> 1.28.0)" - leveldb-library (~> 1.22) - - nanopb (~> 2.30906.0) + - nanopb (~> 2.30908.0) - Flutter (1.0.0) - - GoogleDataTransport (8.1.0): - - nanopb (~> 2.30906.0) + - GoogleDataTransport (9.1.2): + - GoogleUtilities/Environment (~> 7.2) + - nanopb (~> 2.30908.0) + - PromisesObjC (< 3.0, >= 1.2) - GoogleUtilities/Environment (7.6.0): - PromisesObjC (< 3.0, >= 1.2) - GoogleUtilities/Logger (7.6.0): @@ -283,11 +412,11 @@ PODS: - gRPC-Core/Interface (= 1.28.2) - gRPC-Core/Interface (1.28.2) - leveldb-library (1.22.1) - - nanopb (2.30906.0): - - nanopb/decode (= 2.30906.0) - - nanopb/encode (= 2.30906.0) - - nanopb/decode (2.30906.0) - - nanopb/encode (2.30906.0) + - nanopb (2.30908.0): + - nanopb/decode (= 2.30908.0) + - nanopb/encode (= 2.30908.0) + - nanopb/decode (2.30908.0) + - nanopb/encode (2.30908.0) - PromisesObjC (2.0.0) DEPENDENCIES: @@ -322,21 +451,21 @@ EXTERNAL SOURCES: SPEC CHECKSUMS: abseil: 6c8eb7892aefa08d929b39f9bb108e5367e3228f BoringSSL-GRPC: 8edf627ee524575e2f8d19d56f068b448eea3879 - cloud_firestore: 357b92d4778d7715d76a393db5f89e7dcc9b7401 - Firebase: 26223c695fe322633274198cb19dca8cb7e54416 - firebase_core: 91b27774a52f41f8b58484a75edf71197ac01c59 - FirebaseCore: 4d3c72622ce0e2106aaa07bb4b2935ba2c370972 - FirebaseCoreDiagnostics: d50e11039e5984d92c8a512be2395f13df747350 - FirebaseFirestore: 1906bf163afdb7c432d2e3b5c40ceb9dd2df5820 + cloud_firestore: 2cff0618e560f435fc05da5c94c2d213eb7ba640 + Firebase: 13d8d96499e2635428d5bf0ec675df21f95d9a95 + firebase_core: f770e033e790657b3505f04be4cb24c482912f11 + FirebaseCore: 599ee609343eaf4941bd188f85e3aa077ffe325b + FirebaseCoreDiagnostics: 56fb7216d87e0e6ec2feddefa9d8a392fe8b2c18 + FirebaseFirestore: 15ae9648476436efed698a909e44c4737498f9b4 Flutter: 50d75fe2f02b26cc09d224853bb45737f8b3214a - GoogleDataTransport: 116c84c4bdeb76be2a7a46de51244368f9794eab + GoogleDataTransport: 629c20a4d363167143f30ea78320d5a7eb8bd940 GoogleUtilities: 684ee790a24f73ebb2d1d966e9711c203f2a4237 "gRPC-C++": 13d8ccef97d5c3c441b7e3c529ef28ebee86fad2 gRPC-Core: 4afa11bfbedf7cdecd04de535a9e046893404ed5 leveldb-library: 50c7b45cbd7bf543c81a468fe557a16ae3db8729 - nanopb: 1bf24dd71191072e120b83dd02d08f3da0d65e53 + nanopb: a0ba3315591a9ae0a16a309ee504766e90db0c96 PromisesObjC: 68159ce6952d93e17b2dfe273b8c40907db5ba58 PODFILE CHECKSUM: 3efef3e4c4241ddf19165efb8229df7447127bfd -COCOAPODS: 1.10.1 +COCOAPODS: 1.11.2 diff --git a/frontend/lib/main.dart b/frontend/lib/main.dart index a361d71..2c859f5 100644 --- a/frontend/lib/main.dart +++ b/frontend/lib/main.dart @@ -1,12 +1,18 @@ +import 'dart:developer'; + import 'package:flutter/material.dart'; import 'package:src/task.dart'; import 'package:firebase_core/firebase_core.dart'; import 'package:cloud_firestore/cloud_firestore.dart'; import 'package:src/widgets/interactive_task.dart'; +import 'package:src/widgets/stream_task_list.dart'; -void main() { +void main() async { + // FirebaseFirestore.instance.useFirestoreEmulator('localhost', 8080); WidgetsFlutterBinding.ensureInitialized(); - runApp(const TaskScheduler()); + await Firebase.initializeApp(); + // FirebaseFunctions.instance.useFunctionsEmulator('localhost', 5001); + runApp(TaskScheduler()); } class TaskScheduler extends StatelessWidget { @@ -41,7 +47,7 @@ class _MyHomePageState extends State { void initializeFlutterFire() async { try { // Wait for Firebase to initialize and set `_initialized` state to true - await Firebase.initializeApp(); + // await Firebase.initializeApp(); setState(() { _initialized = true; @@ -106,28 +112,7 @@ class _MyHomePageState extends State { children: [ Container( margin: const EdgeInsets.only(top: 20), - child: Column(children: [ - FutureBuilder( - future: tasks.get(), - builder: (_, AsyncSnapshot snapshot) { - return snapshot.hasData - ? Column(children: [ - Container( - height: - MediaQuery.of(context).size.height * 0.4, - child: ListView.builder( - padding: const EdgeInsets.all(4.0), - itemCount: snapshot.data.docs.length, - reverse: false, - itemBuilder: (context, index) { - DocumentSnapshot ds = - snapshot.data.docs[index]; - return InteractiveTask(ds: ds); - })), - ]) - : const Text("NOT CONNECTED TO DATABASE"); - }), - ]), + child: StreamTaskList(), ), if (_toAdd) diff --git a/frontend/lib/task.dart b/frontend/lib/task.dart index c95957b..01180e2 100644 --- a/frontend/lib/task.dart +++ b/frontend/lib/task.dart @@ -4,6 +4,7 @@ import 'package:firebase_core/firebase_core.dart'; import 'package:cloud_firestore/cloud_firestore.dart'; import 'package:src/widgets/interactive_task.dart'; import 'package:date_format/date_format.dart'; +import 'dart:collection'; class Task extends StatefulWidget { const Task( @@ -28,9 +29,10 @@ class _Task extends State { @override Widget build(BuildContext context) { String due = "new"; + dynamic? data = widget.ds?.data(); + if (data == Null) return Container(); try { - DateTime date = - DateTime.parse(widget.ds!.data()["dueDate"].toDate().toString()); + DateTime date = DateTime.parse(data.dueDate.toDate().toString()); due = "Due " + formatDate(date, [M, ' ', d]); } catch (e) {} if (!_done) { @@ -51,23 +53,26 @@ class _Task extends State { child: Column( children: [ Stack(children: [ - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Container( - height: MediaQuery.of(context).size.height * 0.05, - width: MediaQuery.of(context).size.width * 0.40, - child: Align( - alignment: Alignment.centerLeft, - child: Text( - widget.title, - style: const TextStyle( - fontWeight: FontWeight.bold, fontSize: 16), - ), + FractionallySizedBox( + widthFactor: 1, + child: Flex( + direction: Axis.horizontal, + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Align( + alignment: Alignment.centerLeft, + child: Text( + widget.title, + style: const TextStyle( + fontWeight: FontWeight.bold, fontSize: 16), + ), + ), + ], ), - padding: const EdgeInsets.all(8.0), - ), - ], + ], + ), ), Positioned( child: Text( diff --git a/frontend/lib/widgets/interactive_task.dart b/frontend/lib/widgets/interactive_task.dart index a5a0970..4fb4bfe 100644 --- a/frontend/lib/widgets/interactive_task.dart +++ b/frontend/lib/widgets/interactive_task.dart @@ -36,14 +36,15 @@ class InteractiveTask extends StatelessWidget { @override Widget build(BuildContext context) { + dynamic data = ds!.data(); return Dismissible( onDismissed: (direction) => dismissItem(direction), key: UniqueKey(), child: Task( - title: ds!.data()["title"].toString(), - description: ds!.data()["description"].toString() + + title: data["title"].toString(), + description: data["description"].toString() + " [status " + - ds!.data()["status"].toString() + + data["status"].toString() + "]", ds: ds), background: buildSwipeActionLeft(), diff --git a/frontend/lib/widgets/stream_task_list.dart b/frontend/lib/widgets/stream_task_list.dart new file mode 100644 index 0000000..87b1a65 --- /dev/null +++ b/frontend/lib/widgets/stream_task_list.dart @@ -0,0 +1,45 @@ +import 'dart:developer'; + +import 'package:flutter/material.dart'; +import 'package:firebase_core/firebase_core.dart'; +import 'package:cloud_firestore/cloud_firestore.dart'; + +import 'interactive_task.dart'; + +class StreamTaskList extends StatefulWidget { + StreamTaskList({Key? key}) : super(key: key); + + @override + _StreamTaskListState createState() => _StreamTaskListState(); +} + +// Refreshes task list whenever Task data changes +class _StreamTaskListState extends State { + @override + Widget build(BuildContext context) { + return StreamBuilder( + stream: FirebaseFirestore.instance + .collection('testingTaskCollection') + .snapshots(), + builder: (BuildContext context, AsyncSnapshot snapshot) { + if (snapshot.hasError) { + return const Text('Something went wrong'); + } + if (snapshot.connectionState == ConnectionState.waiting) { + return const FractionallySizedBox( + child: Center(child: CircularProgressIndicator()), + widthFactor: 1, + heightFactor: 1, + ); + } + return ListView( + padding: const EdgeInsets.all(4.0), + children: snapshot.data!.docs.map((DocumentSnapshot document) { + return InteractiveTask( + ds: document, + ); + }).toList(), + ); + }); + } +} diff --git a/frontend/pubspec.lock b/frontend/pubspec.lock index 98bacb4..e388852 100644 --- a/frontend/pubspec.lock +++ b/frontend/pubspec.lock @@ -42,21 +42,21 @@ packages: name: cloud_firestore url: "https://pub.dartlang.org" source: hosted - version: "0.16.0+1" + version: "3.1.0" cloud_firestore_platform_interface: dependency: transitive description: name: cloud_firestore_platform_interface url: "https://pub.dartlang.org" source: hosted - version: "3.0.2" + version: "5.4.5" cloud_firestore_web: dependency: transitive description: name: cloud_firestore_web url: "https://pub.dartlang.org" source: hosted - version: "0.3.0+2" + version: "2.5.0" collection: dependency: transitive description: @@ -91,21 +91,21 @@ packages: name: firebase_core url: "https://pub.dartlang.org" source: hosted - version: "0.7.0" + version: "1.10.0" firebase_core_platform_interface: dependency: transitive description: name: firebase_core_platform_interface url: "https://pub.dartlang.org" source: hosted - version: "3.0.1" + version: "4.1.0" firebase_core_web: dependency: transitive description: name: firebase_core_web url: "https://pub.dartlang.org" source: hosted - version: "0.2.1+3" + version: "1.2.0" flutter: dependency: "direct main" description: flutter @@ -128,13 +128,6 @@ packages: description: flutter source: sdk version: "0.0.0" - http_parser: - dependency: transitive - description: - name: http_parser - url: "https://pub.dartlang.org" - source: hosted - version: "3.1.4" js: dependency: transitive description: @@ -176,14 +169,7 @@ packages: name: plugin_platform_interface url: "https://pub.dartlang.org" source: hosted - version: "1.0.3" - quiver: - dependency: transitive - description: - name: quiver - url: "https://pub.dartlang.org" - source: hosted - version: "2.1.5" + version: "2.0.2" sky_engine: dependency: transitive description: flutter diff --git a/frontend/pubspec.yaml b/frontend/pubspec.yaml index 39bb7c7..ba4a3cb 100644 --- a/frontend/pubspec.yaml +++ b/frontend/pubspec.yaml @@ -29,8 +29,8 @@ environment: dependencies: flutter: sdk: flutter - firebase_core: "0.7.0" - cloud_firestore: "^0.16.0" + firebase_core: "^1.10.0" + cloud_firestore: "^3.1.0" # The following adds the Cupertino Icons font to your application. # Use with the CupertinoIcons class for iOS style icons. diff --git a/frontend/web/index.html b/frontend/web/index.html index 88280f4..edec368 100644 --- a/frontend/web/index.html +++ b/frontend/web/index.html @@ -1,7 +1,7 @@ - - - + - - - + + + - - - - - + + + + + - src - - - - - + + + + + + + + + - + // If service worker doesn't succeed in a reasonable amount of time, + // fallback to plaint +