Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

File structure refactoring, fixed AppUser streaming via Provider #55

Merged
merged 5 commits into from
Jan 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 13 additions & 13 deletions lib/authentication/user.dart → lib/data/app_user.dart
Original file line number Diff line number Diff line change
@@ -1,34 +1,36 @@
import 'package:cloud_firestore/cloud_firestore.dart';

class MyUser {
class AppUser {
static final AppUser defaultUser = AppUser(uid: "");

final String uid;
final String? email;
final String? firstName;
final String? lastName;
final GeoPoint? location;

MyUser({required this.uid, this.email, this.firstName, this.lastName, this.location});
AppUser(
{required this.uid,
this.email,
this.firstName,
this.lastName,
this.location});

factory MyUser.fromFirestore(
QueryDocumentSnapshot snapshot,
factory AppUser.fromFirestore(
DocumentSnapshot snapshot,
SnapshotOptions? options,
) {
Map<String, dynamic> data = snapshot.data() as Map<String, dynamic>;

try {
return MyUser(
return AppUser(
uid: data['uid'],
email: data['email'],
firstName: data['firstName'],
lastName: data['lastName'],
location: data['location']);
} catch (e) {
return MyUser(
uid: 'UserID',
email: '[email protected]',
firstName: "First",
lastName: "Last",
location: GeoPoint(0, 0));
return defaultUser;
}
}

Expand All @@ -41,6 +43,4 @@ factory MyUser.fromFirestore(
"location": location,
};
}

}

20 changes: 10 additions & 10 deletions lib/main.dart
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import 'package:flutter/material.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:flutter_native_splash/flutter_native_splash.dart';
import 'package:lost_found_steelhacks/authentication/auth.dart';
import 'package:lost_found_steelhacks/authentication/user.dart';
import 'package:lost_found_steelhacks/authentication/wrapper.dart';
import 'package:lost_found_steelhacks/services/auth_service.dart';
import 'package:lost_found_steelhacks/data/app_user.dart';
import 'package:lost_found_steelhacks/routing/wrapper.dart';
import 'package:lost_found_steelhacks/services/firestore_service.dart';
import 'package:lost_found_steelhacks/data/item.dart';
import 'package:lost_found_steelhacks/themes/app_theme.dart';
Expand Down Expand Up @@ -60,14 +60,14 @@ class _MyAppState extends State<MyApp> {
FlutterNativeSplash.remove();
return MultiProvider(
providers: [
StreamProvider<MyUser?>.value(value: AuthService().user, initialData: null),
StreamProvider<AppUser?>.value(
value: AuthService.appUserStream,
initialData: AppUser.defaultUser,
catchError: (context, error) => null),
StreamProvider<List<Item>>.value(
value: FirestoreService().getFoundItems(),
initialData: [],
catchError: (context, error) {
return [];
},
),
value: FirestoreService.getFoundItemsStream(),
initialData: const [],
catchError: (context, error) => []),
],
child: MaterialApp(
title: 'Lost@Pitt | For Students By Students',
Expand Down
2 changes: 1 addition & 1 deletion lib/pages/list_page.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/material.dart';
import 'package:lost_found_steelhacks/cards/post_card.dart';
import 'package:lost_found_steelhacks/widgets/post_card.dart';
import 'package:lost_found_steelhacks/data/item.dart';
import 'package:lost_found_steelhacks/themes/app_theme.dart';
import 'package:provider/provider.dart';
Expand Down
27 changes: 13 additions & 14 deletions lib/pages/login_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:ionicons/ionicons.dart';
import 'package:lost_found_steelhacks/authentication/auth.dart';
import 'package:lost_found_steelhacks/authentication/loading_animation.dart';
import 'package:lost_found_steelhacks/authentication/user.dart';
import 'package:lost_found_steelhacks/services/auth_service.dart';
import 'package:lost_found_steelhacks/widgets/loading_animation.dart';
import 'package:lost_found_steelhacks/data/app_user.dart';
import 'package:lost_found_steelhacks/themes/app_theme.dart';

class LoginPage extends StatefulWidget {
Expand Down Expand Up @@ -108,9 +108,9 @@ class _LoginPageState extends State<LoginPage> {
);
}

Widget _buildLoginBtn(AppTheme theme, bool loading, AuthService authService) {
Widget _buildLoginBtn(AppTheme theme, bool loading) {
return loading
? const Loading()
? const LoadingAnimation()
: Container(
padding: const EdgeInsets.symmetric(vertical: 25.0),
child: Container(
Expand All @@ -120,18 +120,18 @@ class _LoginPageState extends State<LoginPage> {
if (_formKey.currentState!.validate()) {
setState(() => loading = true);
try {
MyUser? result = await authService
.signInWithEmailAndPassword(_email, _password);
await AuthService.signInWithEmailAndPassword(
_email, _password);

if (result == null) {
if (!AuthService.isSignedIn()) {
throw FirebaseAuthException(code: "Sign in failed");
}

setState(() {
loading = false;
});
//no need to route page as provider handles it
} on FirebaseAuthException catch (e) {
} on FirebaseAuthException {
setState(() {
_error =
'The email or password is incorrect. Please try again.';
Expand All @@ -146,15 +146,15 @@ class _LoginPageState extends State<LoginPage> {
);
}

Widget _buildSocialBtnRow(AppTheme theme, AuthService authService) {
Widget _buildSocialBtnRow(AppTheme theme) {
return Padding(
padding: const EdgeInsets.symmetric(vertical: 15.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
IconButton(
onPressed: () async {
Future result = authService.signInWithGoogle();
Future result = AuthService.signInWithGoogle();
result.then((value) {
if (value == null) {
setState(() {
Expand Down Expand Up @@ -200,7 +200,6 @@ class _LoginPageState extends State<LoginPage> {

@override
Widget build(BuildContext context) {
final AuthService authService = AuthService();
final AppTheme theme = Theme.of(context).extension<AppTheme>()!;
//const Widget spacing = SizedBox(height: 30);

Expand Down Expand Up @@ -234,8 +233,8 @@ class _LoginPageState extends State<LoginPage> {
_buildPasswordTF(theme),
_buildForgotPasswordBtn(theme),
_buildErrorMsg(theme),
_buildLoginBtn(theme, loading, authService),
_buildSocialBtnRow(theme, authService),
_buildLoginBtn(theme, loading),
_buildSocialBtnRow(theme),
_buildSignupBtn(theme),
],
),
Expand Down
13 changes: 6 additions & 7 deletions lib/pages/profile_page.dart
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
// ignore_for_file: slash_for_doc_comments

import 'package:flutter/material.dart';
import 'package:lost_found_steelhacks/authentication/auth.dart';
import 'package:lost_found_steelhacks/data/app_user.dart';
import 'package:lost_found_steelhacks/services/auth_service.dart';
import 'package:provider/provider.dart';

/**
* UI to display the user's profile.
Expand All @@ -15,17 +17,14 @@ class ProfilePage extends StatefulWidget {
}

class ProfilePageState extends State<ProfilePage> {
final authService = AuthService();

@override
Widget build(BuildContext context) {
AppUser user = context.watch<AppUser>();
return Center(
child: Column(children: [
Text("Signed in: ${authService.isSignedIn().toString()}"),
Text("Signed in: ${user.firstName}"),
OutlinedButton(
onPressed: () async {
await authService.signOut();
},
onPressed: () async => await AuthService.signOut(),
child: const Icon(Icons.logout))
]));
}
Expand Down
26 changes: 13 additions & 13 deletions lib/pages/signup_page.dart
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:ionicons/ionicons.dart';
import 'package:lost_found_steelhacks/authentication/auth.dart';
import 'package:lost_found_steelhacks/authentication/loading_animation.dart';
import 'package:lost_found_steelhacks/services/auth_service.dart';
import 'package:lost_found_steelhacks/widgets/loading_animation.dart';
import 'package:lost_found_steelhacks/themes/app_theme.dart';

class SignUpPage extends StatefulWidget {
Expand Down Expand Up @@ -38,6 +38,7 @@ class _SignUpPageState extends State<SignUpPage> {
decoration: theme.textFieldDecoration,
height: 60.0,
child: TextFormField(
onChanged: (value) => firstName = value,
controller: _firstNameController,
validator: (val) => val == null || val.isEmpty
? 'First name cannot be empty.'
Expand Down Expand Up @@ -69,7 +70,7 @@ class _SignUpPageState extends State<SignUpPage> {
decoration: theme.textFieldDecoration,
height: 60.0,
child: TextFormField(
onChanged: (value) => firstName = value,
onChanged: (value) => lastName = value,
controller: _lastNameController,
validator: (val) => val == null || val.isEmpty
? 'Last name cannot be empty.'
Expand Down Expand Up @@ -147,10 +148,9 @@ class _SignUpPageState extends State<SignUpPage> {
);
}

Widget _buildSignUpBtn(
AppTheme theme, bool loading, AuthService authService) {
Widget _buildSignUpBtn(AppTheme theme, bool loading) {
return loading
? const Loading()
? const LoadingAnimation()
: Container(
padding: EdgeInsets.symmetric(vertical: 25.0),
child: Container(
Expand All @@ -162,10 +162,10 @@ class _SignUpPageState extends State<SignUpPage> {
loading = true;
});

dynamic result =
await authService.registerWithEmailAndPassword(
bool success =
await AuthService.registerWithEmailAndPassword(
firstName, lastName, _email, _password);
if (result == null) {
if (success) {
setState(() {
_error =
'Failed to register with your email and password. Please try again.';
Expand All @@ -184,15 +184,15 @@ class _SignUpPageState extends State<SignUpPage> {
);
}

Widget _buildSocialBtnRow(AppTheme theme, AuthService authService) {
Widget _buildSocialBtnRow(AppTheme theme) {
return Padding(
padding: const EdgeInsets.symmetric(vertical: 15.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
IconButton(
onPressed: () async {
Future result = authService.signInWithGoogle();
Future result = AuthService.signInWithGoogle();
result.then((value) {
if (value == null) {
setState(() {
Expand Down Expand Up @@ -275,8 +275,8 @@ class _SignUpPageState extends State<SignUpPage> {
_buildEmailTF(theme),
_buildSpacing(),
_buildPasswordTF(theme),
_buildSignUpBtn(theme, loading, authService),
_buildSocialBtnRow(theme, authService),
_buildSignUpBtn(theme, loading),
_buildSocialBtnRow(theme),
_buildSignInBtn(theme),
],
),
Expand Down
10 changes: 5 additions & 5 deletions lib/pages/submission_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ import 'dart:typed_data';
import 'package:flutter/material.dart';
import 'package:flutter_fast_forms/flutter_fast_forms.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';
import 'package:lost_found_steelhacks/authentication/loading_animation.dart';
import 'package:lost_found_steelhacks/authentication/user.dart';
import 'package:lost_found_steelhacks/widgets/loading_animation.dart';
import 'package:lost_found_steelhacks/data/app_user.dart';
import 'package:lost_found_steelhacks/data/item.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_storage/firebase_storage.dart';
Expand Down Expand Up @@ -80,7 +80,7 @@ class _SubmissionPageState extends State<SubmissionPage> {
Future<void> addFound() {
Item item = Item(
id: "",
userId: context.read<MyUser?>()!.uid,
userId: context.read<AppUser?>()!.uid,
timeCreated: Timestamp.now(),
description: description,
itemName: itemName,
Expand All @@ -89,7 +89,7 @@ class _SubmissionPageState extends State<SubmissionPage> {
picture: imageName);

// Calling the collection to add a new user
return FirestoreService().addItemToFirestore(item, false);
return FirestoreService.addItemToFirestore(item, false);
}

void submitItem() async {
Expand Down Expand Up @@ -220,7 +220,7 @@ class _SubmissionPageState extends State<SubmissionPage> {
: const SizedBox(height: 1);

Widget buildSubmitButton() => loading
? const Loading()
? const LoadingAnimation()
: TextButton.icon(
label: Text("Submit", style: theme.darkSubtitleStyle),
icon: Icon(Icons.add_box_rounded, color: theme.dark),
Expand Down
15 changes: 8 additions & 7 deletions lib/authentication/wrapper.dart → lib/routing/wrapper.dart
Original file line number Diff line number Diff line change
@@ -1,21 +1,22 @@
import 'package:flutter/material.dart';
import 'package:lost_found_steelhacks/authentication/user.dart';
import 'package:lost_found_steelhacks/data/app_user.dart';
import 'package:lost_found_steelhacks/pages/authenticate_page.dart';
import 'package:lost_found_steelhacks/pages/home_page.dart';
import 'package:lost_found_steelhacks/pages/login_page.dart';
import 'package:lost_found_steelhacks/widgets/loading_animation.dart';
import 'package:provider/provider.dart';

class Wrapper extends StatelessWidget {
const Wrapper({super.key});

@override
Widget build(BuildContext context) {
final user = Provider.of<MyUser?>(context);

if (user == null) {
return AuthenticatePage();
final user = Provider.of<AppUser?>(context);
if (user == AppUser.defaultUser) {
return const LoadingAnimation();
} else if (user == null) {
return const AuthenticatePage();
} else {
return HomePage();
return const HomePage();
}
}
}
Loading