Skip to content

Commit

Permalink
Merge pull request #179 from bhoomikshetty/chore/128-send-emails-to-n…
Browse files Browse the repository at this point in the history
…ew-user-upon-sign-in

chore(#128) : send emails to new user upon sign in
  • Loading branch information
JordyHers authored Oct 4, 2023
2 parents 0f57648 + fc6e4e4 commit 2838417
Show file tree
Hide file tree
Showing 7 changed files with 187 additions and 8 deletions.
2 changes: 1 addition & 1 deletion lib/app/landing_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ class _LandingPageState extends State<LandingPage> {
AuthBase auth,
) {
return Provider<Database>(
create: (_) => FireStoreDatabase(uid: user.uid),
create: (_) => FireStoreDatabase(auth: auth, uid: user.uid,),
child: FutureProvider(
initialData: null,
create: (context) => geoService.getInitialLocation(),
Expand Down
25 changes: 25 additions & 0 deletions lib/models/email_model.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
class EmailModel{

EmailModel({
required this.emailIds,
required this.subject,
required this.text,
required this.html,
});

final List<String> emailIds;
final String subject;
final String text;
final String html;

Map<String, dynamic> toJson() {
return {
'to' : emailIds,
'message' : {
'subject' : subject,
'text' : text,
'html' : html,
}
};
}
}
1 change: 1 addition & 0 deletions lib/services/api_path.dart
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,6 @@ class APIPath {
static String notificationsStream(String uid, String childId) =>
'users/$uid/notifications/';

static String mail() => 'mail/';
static String deviceToken() => 'DeviceTokens/';
}
24 changes: 22 additions & 2 deletions lib/services/auth.dart
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
// ignore_for_file: avoid_setters_without_getters

import 'package:firebase_auth/firebase_auth.dart';
import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter_login_facebook/flutter_login_facebook.dart';
Expand All @@ -7,6 +9,10 @@ import 'package:times_up_flutter/common_widgets/show_logger.dart';
abstract class AuthBase {
User? get currentUser;

bool get isFirstLogin;

void setFirstLogin({bool isFirstLogin});

Future<User> signInAnonymously();

Future<String> setToken();
Expand All @@ -33,15 +39,24 @@ class Auth implements AuthBase {
final _firebaseAuth = FirebaseAuth.instance;
final FirebaseMessaging _firebaseMessaging = FirebaseMessaging.instance;
late String _token;
bool _isFirstLogin = false;

String get token => _token;

@override
void setFirstLogin({bool isFirstLogin = false}) {
_isFirstLogin = isFirstLogin;
}

@override
Stream<User?> authStateChanges() => _firebaseAuth.authStateChanges();

@override
User? get currentUser => _firebaseAuth.currentUser;

@override
bool get isFirstLogin => _isFirstLogin;

@override
Future<User> signInAnonymously() async {
final userCredential = await _firebaseAuth.signInAnonymously();
Expand Down Expand Up @@ -81,6 +96,8 @@ class Auth implements AuthBase {
email: email,
password: password,
);
_isFirstLogin = userCredential.additionalUserInfo!.isNewUser;

JHLogger.$.v('Sign Up user complete Name : $name');
return userCredential.user!;
}
Expand All @@ -99,6 +116,8 @@ class Auth implements AuthBase {
accessToken: googleAuth.accessToken,
),
);
_isFirstLogin = userCredential.additionalUserInfo!.isNewUser;

return userCredential.user!;
} else {
throw FirebaseAuthException(
Expand Down Expand Up @@ -130,8 +149,9 @@ class Auth implements AuthBase {
final userCredential = await _firebaseAuth.signInWithCredential(
FacebookAuthProvider.credential(accessToken!.token),
);
JHLogger.$.v('Facebook Login Completed : ${accessToken.token}');
_isFirstLogin = userCredential.additionalUserInfo!.isNewUser;

JHLogger.$.v('Facebook Login Completed : ${accessToken.token}');
return userCredential.user!;

case FacebookLoginStatus.cancel:
Expand Down Expand Up @@ -163,7 +183,7 @@ class Auth implements AuthBase {
default:
break;
}

_isFirstLogin = false;
await _firebaseAuth.signOut();
}
}
35 changes: 30 additions & 5 deletions lib/services/database.dart
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:times_up_flutter/common_widgets/show_logger.dart';
import 'package:times_up_flutter/models/child_model/child_model.dart';
import 'package:times_up_flutter/models/email_model.dart';
import 'package:times_up_flutter/models/notification_model/notification_model.dart';
import 'package:times_up_flutter/services/api_path.dart';
import 'package:times_up_flutter/services/app_usage_service.dart';
import 'package:times_up_flutter/services/auth.dart';
import 'package:times_up_flutter/services/firestore_service.dart';
import 'package:times_up_flutter/services/geo_locator_service.dart';
import 'package:times_up_flutter/utils/constants.dart';

abstract class Database {
Future<void> setChild(ChildModel model);
Expand Down Expand Up @@ -34,6 +36,8 @@ abstract class Database {
ChildModel model,
);

Future<void> sendEmail({required EmailModel email});

Future<ChildModel> getUserCurrentChild(
String key,
AppUsageService apps,
Expand All @@ -45,11 +49,24 @@ abstract class Database {
class FireStoreDatabase implements Database {
FireStoreDatabase({
required this.uid,
this.auth,
});
required this.auth,
}) {
if (auth.isFirstLogin) {
sendEmail(
email: EmailModel(
emailIds: [auth.currentUser!.email!],
subject: EmailConstants.subject,
text: EmailConstants.text,
html: EmailConstants.html(
auth.currentUser!.displayName ?? auth.currentUser!.email!,
),
),
).then((value) => auth.setFirstLogin(isFirstLogin: false));
}
}

final String uid;
final AuthBase? auth;
final AuthBase auth;
ChildModel? _child;

ChildModel get currentChild => _child!;
Expand Down Expand Up @@ -81,6 +98,14 @@ class FireStoreDatabase implements Database {
);
}

@override
Future<void> sendEmail({required EmailModel email}) async {
await _service.sendEmail(
path: APIPath.mail(),
data: email.toJson(),
);
}

Future<void> setTokenOnFireStore(Map<String, dynamic> token) async {
await _service.setNotificationFunction(
path: APIPath.deviceToken(),
Expand Down Expand Up @@ -154,8 +179,8 @@ class FireStoreDatabase implements Database {
GeoPoint latLong, {
String? battery,
}) async {
final user = auth?.currentUser?.uid;
final token = await auth?.setToken();
final user = auth.currentUser?.uid;
final token = await auth.setToken();
await apps.getAppUsageService();
await setTokenOnFireStore(
{'id': user, 'childId': key, 'device_token': '$token'},
Expand Down
19 changes: 19 additions & 0 deletions lib/services/firestore_service.dart
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,25 @@ class FireStoreService {
await reference.set(data);
}

Future<void> sendEmail({
required String path,
required Map<String, dynamic> data,
}) async {
await FirebaseFirestore.instance.collection(path).doc().set(data);
JHLogger.$.d('Welcome email sent to ${data['to']}');
}

Future<void> saveToken({
required String path,
required Map<String, dynamic> data,
}) async {
final reference = FirebaseFirestore.instance.collection(path).doc();
JHLogger.$.d('$path: $data');

await reference.set(data);
}


Future<void> deleteData({required String path, String? image}) async {
final reference = FirebaseFirestore.instance.doc(path);
if (image != null) {
Expand Down
89 changes: 89 additions & 0 deletions lib/utils/constants.dart
Original file line number Diff line number Diff line change
@@ -1,7 +1,96 @@
import 'package:flutter/material.dart';

import 'package:times_up_flutter/utils/app_strings.dart';

class Keys {
static const emailKeys = Key('emailLoginKey');
static const geoFullKeys = Key('geoFullKey');
static const googleMapKeys = Key('googleMaplKey');
}

class EmailConstants {
static const subject = "Time's up - Welcome email";
static const text = '';

static const welcomeHeaderText = 'Welcome to ${Strings.appName}';
static const logoImageUrl =
'https://firebasestorage.googleapis.com/v0/b/demooo-6e52b.appspot.com/o/time%2Foutput-onlinepngtools.png?alt=media&token=5755f1a1-4576-43c7-a542-04860361404d&_gl=1*1jyiwv9*_ga*NjE3NTkxMTQ2LjE2ODY1ODAyODg.*_ga_CW55HF8NVT*MTY5NjMzMTY4NC45NC4xLjE2OTYzMzQ0MjguMzguMC4w.jpg';
static const giphyCode = '''
''';
// '''
// <div style="padding-top:75.000%;position:relative;"><iframe src="https://firebasestorage.googleapis.com/v0/b/demooo-6e52b.appspot.com/o/time%2Fezgif.com-optimize%20(1).gif?alt=media&token=24a48377-78a2-4da8-bfda-a9be4f01f4d9&_gl=1*1i9c6ta*_ga*NjE3NTkxMTQ2LjE2ODY1ODAyODg.*_ga_CW55HF8NVT*MTY5NjMzMTY4NC45NC4xLjE2OTYzMzc5MDUuNTMuMC4w" width="100%" height="100%" style='position:absolute;top:0;left:0;' frameBorder="0" allowFullScreen></iframe></div><p><a href="https://gifer.com">via GIFER</a></p>
// ''';

static const body = '''
<p>We are thrilled to have you as a new member of our community. Your presence means a lot to us!</p>
<p>Thank you for joining us!</p>
<p>Best regards,</p>
<p>Time's up Team</p>''';

static const style = '''
<style>
body {
font-family: Arial, sans-serif;
background-color: #3A4EDC; /* Set the background color to #3A4EDC */
margin: 0;
padding: 0;
}
.container {
max-width: 600px;
margin: 0 auto;
padding: 20px;
background-color: #ffffff;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
border-radius: 4px;
}
.header {
text-align: center;
padding: 20px 0;
}
h1 {
color: #333;
}
p {
color: #666;
}
.logo {
display: block;
margin: 0 auto;
width: 200px;
border-radius: 6px;
}
.giphy {
text-align: center;
}
</style>
''';

// ignore: leading_newlines_in_multiline_strings
static String html(String username) => '''
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>${EmailConstants.welcomeHeaderText}</title>
${EmailConstants.style}
</head>
<body>
<div class="container">
<div class="header">
<img class="logo" src=${EmailConstants.logoImageUrl} alt="Welcome Logo">
</div>
<h1>${EmailConstants.welcomeHeaderText}</h1>
<div class="giphy">
$giphyCode
</div>
<p>Dear $username,</p>
${EmailConstants.body}
</div>
</body>
</html>
''';
}

0 comments on commit 2838417

Please sign in to comment.