From ecbf3b74732c5a8c276121d1f4e3bc9127bf09c0 Mon Sep 17 00:00:00 2001
From: Himali Aryal <himalia@stud.ntnu.no>
Date: Mon, 19 Apr 2021 20:54:35 +0200
Subject: [PATCH] Added authentication

---
 lib/main.dart                            | 77 +++++++++++++++++--
 lib/ui/auth/log_in.dart                  | 98 ++++++++++++++++++++++++
 lib/ui/common/notification_provider.dart | 25 +++---
 lib/ui/entries/add_entries.dart          |  7 +-
 lib/ui/entries/emoji_entries.dart        |  5 +-
 pubspec.lock                             |  7 ++
 pubspec.yaml                             |  1 +
 7 files changed, 202 insertions(+), 18 deletions(-)
 create mode 100644 lib/ui/auth/log_in.dart

diff --git a/lib/main.dart b/lib/main.dart
index e1586d4..a0b0e2b 100644
--- a/lib/main.dart
+++ b/lib/main.dart
@@ -1,5 +1,8 @@
 import 'dart:async';
+import 'package:firebase_auth/firebase_auth.dart';
+import 'package:firebase_core/firebase_core.dart';
 import 'package:flutter/material.dart';
+import 'package:flutter_app/ui/auth/log_in.dart';
 import 'package:flutter_app/ui/common/notification_provider.dart';
 import 'package:flutter_app/ui/entries/list_entries.dart';
 import 'package:flutter_app/ui/entries/select_page.dart';
@@ -13,9 +16,67 @@ import 'package:workmanager/workmanager.dart';
 //   });
 // }
 
-void main() => runApp(MaterialApp(
-  home: Home(),
-));
+void main()  {
+  runApp(MaterialApp(
+    home: MyApp(),
+  ));
+}
+
+class MyApp extends StatelessWidget {
+  @override
+  Widget build(BuildContext context) {
+    return MaterialApp(
+      home: LandingPage(),
+    );
+  }
+}
+
+class LandingPage extends StatelessWidget {
+  final Future<FirebaseApp> _initialization = Firebase.initializeApp();
+  @override
+  Widget build(BuildContext context) {
+    return FutureBuilder(
+        future: _initialization,
+        builder: (context, snapshot){
+          if(snapshot.hasError){
+            return Scaffold(
+              body: Center(
+                child: Text("Error: ${snapshot.error}"),
+              ),
+            );
+          }
+          if(snapshot.connectionState == ConnectionState.done){
+            return StreamBuilder(
+              stream: FirebaseAuth.
+              instance
+                  .authStateChanges(),
+              builder: (context, snapshot){
+                if(snapshot.connectionState == ConnectionState.active){
+                  User user = snapshot.data;
+                  if(user == null){
+                    return LoginPage();
+                  }else{
+                    return Home();
+                  }
+                }
+                return Scaffold(
+                  body: Center(
+                    child: Text('Connecting authentication...'),
+                  ),
+                );
+              },
+            );
+          }
+          return Scaffold(
+            body: Center(
+              child: Text('Connecting to the app...'),
+            ),
+          );
+        }
+    );
+  }
+}
+
 
 class Home extends StatefulWidget {
   static const routeName = 'home';
@@ -35,11 +96,17 @@ class _HomeState extends State<Home> {
             backgroundColor: Color(0xFF3C4858),
             actions: <Widget>[
               IconButton(
-                icon: Icon(Icons.settings),
+                icon: Icon(Icons.notifications),
                 onPressed: () {
                   Navigator.of(context).push(SlideUpRoute(widget: NotificationProvider()));
                 },
-              )
+              ),
+              IconButton(
+                  icon: Icon(Icons.settings),
+                  onPressed: () async{
+                    await FirebaseAuth.instance.signOut();
+                  },
+              ),
             ],
         ),
         body: IndexedStack(
diff --git a/lib/ui/auth/log_in.dart b/lib/ui/auth/log_in.dart
new file mode 100644
index 0000000..e103487
--- /dev/null
+++ b/lib/ui/auth/log_in.dart
@@ -0,0 +1,98 @@
+import 'package:flutter/material.dart';
+import 'package:firebase_auth/firebase_auth.dart';
+
+
+class LoginPage extends StatefulWidget {
+  @override
+  _LoginPageState createState() => _LoginPageState();
+}
+
+class _LoginPageState extends State<LoginPage> {
+
+  String _email;
+  String _password;
+
+  Future<void> _createUser() async{
+    try{
+      UserCredential userCredential = await FirebaseAuth
+          .instance
+          .createUserWithEmailAndPassword(email: _email, password: _password);
+    } on FirebaseAuthException catch(e){
+      showAlert();
+    }catch(e){
+      showAlert();
+    }
+  }
+  void showAlert() {
+    showDialog(context: context, builder: (context) {
+      return AlertDialog(
+        title: Text('Incorrect user name or password...'),
+      );
+    });
+  }
+
+  Future<void> _login() async{
+    try{
+      UserCredential userCredential = await FirebaseAuth
+          .instance
+          .signInWithEmailAndPassword(email: _email, password: _password);
+    } on FirebaseAuthException catch(e){
+      showAlert();
+    }catch(e){
+      showAlert();
+    }
+  }
+
+  @override
+  Widget build(BuildContext context) {
+    return Scaffold(
+      appBar: AppBar(
+        title: Text('Login'),
+        backgroundColor: Color(0xFF3C4858),
+        centerTitle: true,
+      ),
+      body: Padding(
+        padding: const EdgeInsets.all(16.0),
+        child: Column(
+          mainAxisAlignment: MainAxisAlignment.start,
+          children: [
+            TextField(
+              onChanged: (value){
+                _email = value;
+              },
+              decoration: InputDecoration(
+                hintText: 'Enter Email...'
+              ),
+            ),
+            TextField(
+              onChanged: (value){
+                _password = value;
+              },
+                obscureText: true,
+              decoration: InputDecoration(
+                  hintText: 'Enter Password...'
+              ),
+            ),
+            Row(
+              mainAxisAlignment: MainAxisAlignment.spaceEvenly,
+              children: [
+                MaterialButton(
+                  onPressed: (){
+                    _login();
+                  },
+                  child: Text('Login'),
+                ),
+                MaterialButton(
+                  onPressed: (){
+                    _createUser();
+                  },
+                  child: Text('Register'),
+                ),
+              ],
+            ),
+          ],
+        ),
+      ),
+    );
+  }
+}
diff --git a/lib/ui/common/notification_provider.dart b/lib/ui/common/notification_provider.dart
index 015ad54..6a010b0 100644
--- a/lib/ui/common/notification_provider.dart
+++ b/lib/ui/common/notification_provider.dart
@@ -1,5 +1,6 @@
 import 'dart:async';
 
+import 'package:flutter/cupertino.dart';
 import 'package:flutter/material.dart';
 import 'package:flutter/scheduler.dart';
 import 'package:flutter_app/ui/common/slide_up_route.dart';
@@ -31,19 +32,14 @@ class _NotificationProviderState extends State<NotificationProvider> {
 
 
   Future _showNotification() async {
-
     var androidDetails = new AndroidNotificationDetails(
         "Notification ID", "Diary notification provider", "This is reminder to add daily diary to your app",
         importance: Importance.max,
-    // playSound: true,
-    // sound: RawResourceAndroidNotificationSound('Notification sound')
     );
     var iSODetails = new IOSNotificationDetails();
     var generalNotificationDetails =
     new NotificationDetails(android: androidDetails, iOS: iSODetails);
 
-    // await fltrNotification.show(
-    //     0, "Task", "You created a Task", generalNotificationDetails, payload: "Task");
     var scheduledTime;
     if (_selectedParam == "Hour") {
       scheduledTime = DateTime.now().add(Duration(hours: val));
@@ -52,12 +48,11 @@ class _NotificationProviderState extends State<NotificationProvider> {
       scheduledTime = DateTime.now().add(Duration(minutes: val));
     } else {
       scheduledTime = DateTime.now().add(Duration(seconds: val));
-      // scheduledTime = Timer.periodic(scheduledTime,(timer){});
     }
 
 
-    fltrNotification.schedule(
-        1, "DIARY NOTIFICATION", task, scheduledTime, generalNotificationDetails);
+    fltrNotification.periodicallyShow(
+        1, "DIARY NOTIFICATION", task, scheduledTime, generalNotificationDetails, androidAllowWhileIdle: true);
   }
 
 
@@ -213,10 +208,18 @@ class _NotificationProviderState extends State<NotificationProvider> {
       context: context,
       builder: (context) => AlertDialog(
         content: Text("Notification Clicked $payload"),
+        actions: [
+          CupertinoDialogAction(
+            isDefaultAction: true,
+            child: Text('ok'),
+            onPressed: () async{
+              Navigator.of(context, rootNavigator: true).pop();
+              await Navigator.push(context, SlideUpRoute(widget: AddEntry()));
+            },
+            // onPressed: () => Navigator.of(context).push(SlideUpRoute(widget: AddEntry())),
+          )
+        ],
       ),
     );
-    GestureDetector(
-        onTap: () => Navigator.of(context).push(SlideUpRoute(widget: AddEntry())),
-    );
   }
 }
diff --git a/lib/ui/entries/add_entries.dart b/lib/ui/entries/add_entries.dart
index 676ce36..7f8672e 100644
--- a/lib/ui/entries/add_entries.dart
+++ b/lib/ui/entries/add_entries.dart
@@ -1,8 +1,10 @@
+import 'package:firebase_auth/firebase_auth.dart';
 import 'package:firebase_core/firebase_core.dart';
 import 'package:firebase_database/firebase_database.dart';
 import 'package:flutter_app/utils/input_validator.dart';
 import 'package:flutter/material.dart';
 import 'package:flutter/services.dart';
+import 'package:firebase_auth/firebase_auth.dart';
 
 
 class AddEntry extends StatefulWidget {
@@ -26,14 +28,17 @@ class _AddEntryState extends State<AddEntry> {
     _contentController =  TextEditingController();
     _ref = FirebaseDatabase.instance.reference().child('diary');
   }
+
   Widget build(BuildContext context) {
     void saveContent() {
       String title = _titleController.text;
       String content = _contentController.text;
+      String user = FirebaseAuth.instance.currentUser.uid;
       Map<String, String> diary = {
+        'uid': user,
         'title' : title,
         'content' : content,
-        'Created at' : DateTime.now().toString(),
+        'Timestamp' : DateTime.now().millisecondsSinceEpoch.toString(),
       };
       _ref.push().set(diary).then((value) {
         Navigator.of(context).pop();
diff --git a/lib/ui/entries/emoji_entries.dart b/lib/ui/entries/emoji_entries.dart
index 225e940..2969f41 100644
--- a/lib/ui/entries/emoji_entries.dart
+++ b/lib/ui/entries/emoji_entries.dart
@@ -1,3 +1,4 @@
+import 'package:firebase_auth/firebase_auth.dart';
 import 'package:firebase_database/firebase_database.dart';
 import 'package:flutter/cupertino.dart';
 import 'package:flutter/material.dart';
@@ -25,9 +26,11 @@ class _EmojisState extends State<Emojis> {
     void saveContent(String title) {
       setState(() {
         _typeSelected = title;
-        _createdAt = DateTime.now().toString();
+        _createdAt = DateTime.now().millisecondsSinceEpoch.toString();
       });
+      String user = FirebaseAuth.instance.currentUser.uid;
       Map<String, String> emojis = {
+        'uid' : user,
         'content' : _typeSelected,
         'Timestamp' : _createdAt,
       };
diff --git a/pubspec.lock b/pubspec.lock
index 5f20702..49deef7 100644
--- a/pubspec.lock
+++ b/pubspec.lock
@@ -190,6 +190,13 @@ packages:
       url: "https://pub.dartlang.org"
     source: hosted
     version: "4.4.0"
+  firebase_dynamic_links:
+    dependency: "direct dev"
+    description:
+      name: firebase_dynamic_links
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "0.6.3"
   flutter:
     dependency: "direct main"
     description: flutter
diff --git a/pubspec.yaml b/pubspec.yaml
index a83db43..79a97e7 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -63,6 +63,7 @@ dev_dependencies:
   intl: ^0.16.0
   flutter_local_notifications: ^4.0.1+2
   rxdart: ^0.23.1
+  firebase_dynamic_links: ^0.6.3
 
 # For information on the generic Dart part of this file, see the
 # following page: https://dart.dev/tools/pub/pubspec
-- 
GitLab