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