Skip to content

Commit 080a4c5

Browse files
author
Okanlawon Jamiu
committed
Complete Initial Implementation
1 parent 6d95707 commit 080a4c5

9 files changed

Lines changed: 102 additions & 14 deletions

File tree

lib/main.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
import 'package:books/src/core/constants/strings.dart';
21
import 'package:firebase_core/firebase_core.dart';
32
import 'package:flutter/material.dart';
43
import 'package:hooks_riverpod/hooks_riverpod.dart';
54

5+
import 'src/core/constants/strings.dart';
66
import 'src/core/routes.dart';
77
import 'src/core/theme.dart';
88
import 'src/features/startup/views/startup_view.dart';

lib/src/core/constants/strings.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ class AppStrings {
4848
static const changeEmail = 'Change Email';
4949
static const changePassword = 'Change Password';
5050
static const logout = 'Logout';
51+
static const deleteAccount = 'Delete Account';
5152
static const updateEmail = 'Update Email Address';
5253
static const updatePassword = 'Update Password';
5354
static const oldPassword = 'Old Password';

lib/src/features/books/views/books_view.dart

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
1-
import 'package:books/src/core/constants/strings.dart';
2-
import 'package:books/src/core/routes.dart';
3-
import 'package:books/src/services/navigation_service.dart';
41
import 'package:flutter/material.dart';
52
import 'package:flutter_hooks/flutter_hooks.dart';
63
import 'package:hooks_riverpod/hooks_riverpod.dart';
74

85
import '../../../core/constants/colors.dart';
96
import '../../../core/constants/dimensions.dart';
7+
import '../../../core/constants/strings.dart';
8+
import '../../../core/routes.dart';
109
import '../../../core/utilities/base_change_notifier.dart';
10+
import '../../../services/navigation_service.dart';
1111
import '../../../widgets/pill.dart';
1212
import '../../../widgets/responsive.dart';
1313
import '../../../widgets/spacing.dart';

lib/src/features/profile/notifiers/profile_notifier.dart

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@ import 'package:hooks_riverpod/hooks_riverpod.dart';
44
import '../../../core/routes.dart';
55
import '../../../core/utilities/base_change_notifier.dart';
66
import '../../../repositories/authentication_repository.dart';
7+
import '../../../services/base/failure.dart';
78
import '../../../services/navigation_service.dart';
9+
import '../../../services/snackbar_service.dart';
810

911
class ProfileNotifier extends BaseChangeNotifier {
1012
ProfileNotifier(this._read);
@@ -21,6 +23,25 @@ class ProfileNotifier extends BaseChangeNotifier {
2123
(_) => false,
2224
);
2325
}
26+
27+
Future<void> deleteUser() async {
28+
try {
29+
setState(state: AppState.loading);
30+
31+
final message = await _read(authenticationRepository).deleteUser();
32+
33+
_read(navigationService).navigateOffAllNamed(
34+
Routes.login,
35+
(_) => false,
36+
);
37+
38+
_read(snackbarService).showSuccessSnackBar(message);
39+
} on Failure catch (f) {
40+
_read(snackbarService).showErrorSnackBar(f.message);
41+
} finally {
42+
setState(state: AppState.idle);
43+
}
44+
}
2445
}
2546

2647
final profileNotifierProvider = ChangeNotifierProvider.autoDispose(

lib/src/features/profile/views/profile_view.dart

Lines changed: 28 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -94,17 +94,35 @@ class ProfileView extends ConsumerWidget {
9494
),
9595
),
9696
const Spacing.largeHeight(),
97-
ElevatedButton(
98-
child: const Text(AppStrings.logout),
99-
style: ElevatedButton.styleFrom(
100-
primary: colorScheme.secondary,
101-
minimumSize: const Size(140, 40),
102-
shape: RoundedRectangleBorder(
103-
borderRadius: BorderRadius.circular(16),
97+
Row(
98+
mainAxisAlignment: MainAxisAlignment.center,
99+
children: [
100+
ElevatedButton(
101+
child: const Text(AppStrings.logout),
102+
style: ElevatedButton.styleFrom(
103+
primary: colorScheme.secondary,
104+
minimumSize: const Size(140, 40),
105+
shape: RoundedRectangleBorder(
106+
borderRadius: BorderRadius.circular(16),
107+
),
108+
),
109+
onPressed:
110+
context.read(profileNotifierProvider).logoutUser,
104111
),
105-
),
106-
onPressed:
107-
context.read(profileNotifierProvider).logoutUser,
112+
const Spacing.mediumWidth(),
113+
ElevatedButton(
114+
child: const Text(AppStrings.deleteAccount),
115+
style: ElevatedButton.styleFrom(
116+
primary: colorScheme.secondary,
117+
minimumSize: const Size(140, 40),
118+
shape: RoundedRectangleBorder(
119+
borderRadius: BorderRadius.circular(16),
120+
),
121+
),
122+
onPressed:
123+
context.read(profileNotifierProvider).deleteUser,
124+
),
125+
],
108126
),
109127
],
110128
),

lib/src/repositories/authentication_repository.dart

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import 'package:cloud_functions/cloud_functions.dart';
12
import 'package:firebase_auth/firebase_auth.dart';
23
import 'package:flutter/foundation.dart';
34
import 'package:google_sign_in/google_sign_in.dart';
@@ -9,10 +10,12 @@ import '../services/base/failure.dart';
910
class AuthenticationRepository {
1011
AuthenticationRepository({
1112
required this.firebaseAuth,
13+
required this.firebaseFunctions,
1214
required this.googleSignIn,
1315
});
1416

1517
final FirebaseAuth firebaseAuth;
18+
final FirebaseFunctions firebaseFunctions;
1619
final GoogleSignIn googleSignIn;
1720

1821
User? get currentUser => firebaseAuth.currentUser;
@@ -25,6 +28,9 @@ class AuthenticationRepository {
2528
password: params.password,
2629
);
2730

31+
// I'm not creating a new user on firestore and using this instead
32+
// because all I have to store is full name and the firebase auth user
33+
// object is faster to access
2834
_userCredential.user!.updateDisplayName(params.fullName);
2935

3036
await _userCredential.user!.sendEmailVerification();
@@ -129,6 +135,23 @@ class AuthenticationRepository {
129135
}
130136
}
131137

138+
Future<String> deleteUser() async {
139+
try {
140+
final HttpsCallable callable = firebaseFunctions.httpsCallable(
141+
'deleteUserAccount',
142+
options: HttpsCallableOptions(timeout: const Duration(seconds: 10)),
143+
);
144+
145+
final result = await callable();
146+
147+
logout();
148+
149+
return result.data;
150+
} on FirebaseFunctionsException catch (ex) {
151+
throw Failure(ex.message ?? 'Something went wrong!');
152+
}
153+
}
154+
132155
Future<void> logout() async {
133156
if (!kIsWeb) {
134157
await googleSignIn.signOut();
@@ -140,6 +163,7 @@ class AuthenticationRepository {
140163
final authenticationRepository = Provider(
141164
(ref) => AuthenticationRepository(
142165
firebaseAuth: FirebaseAuth.instance,
166+
firebaseFunctions: FirebaseFunctions.instance,
143167
googleSignIn: GoogleSignIn(),
144168
),
145169
);

macos/Flutter/GeneratedPluginRegistrant.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,14 @@ import FlutterMacOS
66
import Foundation
77

88
import cloud_firestore
9+
import cloud_functions
910
import firebase_auth
1011
import firebase_core
1112
import path_provider_macos
1213

1314
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
1415
FLTFirebaseFirestorePlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseFirestorePlugin"))
16+
FLTFirebaseFunctionsPlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseFunctionsPlugin"))
1517
FLTFirebaseAuthPlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseAuthPlugin"))
1618
FLTFirebaseCorePlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseCorePlugin"))
1719
PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin"))

pubspec.lock

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,27 @@ packages:
8585
url: "https://pub.dartlang.org"
8686
source: hosted
8787
version: "2.4.3"
88+
cloud_functions:
89+
dependency: "direct main"
90+
description:
91+
name: cloud_functions
92+
url: "https://pub.dartlang.org"
93+
source: hosted
94+
version: "3.0.4"
95+
cloud_functions_platform_interface:
96+
dependency: transitive
97+
description:
98+
name: cloud_functions_platform_interface
99+
url: "https://pub.dartlang.org"
100+
source: hosted
101+
version: "5.0.11"
102+
cloud_functions_web:
103+
dependency: transitive
104+
description:
105+
name: cloud_functions_web
106+
url: "https://pub.dartlang.org"
107+
source: hosted
108+
version: "4.0.13"
88109
collection:
89110
dependency: transitive
90111
description:

pubspec.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ dependencies:
2020
firebase_core: ^1.7.0
2121
firebase_auth: ^3.1.3
2222
cloud_firestore: ^2.5.3
23+
cloud_functions: ^3.0.4
2324
google_sign_in: ^5.1.1
2425

2526
dev_dependencies:

0 commit comments

Comments
 (0)