Skip to content

feature/phone-auth #8

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

Open
wants to merge 35 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
379ac72
refactor: organize asset constants
Jul 10, 2024
255019f
fix: correct path typo from 'assets/image' to 'assets/images'
Jul 10, 2024
fed66e8
Add Firebase configuration and setup Android/iOS platforms
neminsheth Jul 12, 2024
c11c794
Working: TODO: Ensure Reset Password has Email verification
neminsheth Jul 12, 2024
7f2c166
Working: TODO: Ensure Reset Password has Email verification
neminsheth Jul 12, 2024
39ab12e
Merge pull request #1 from HardikSJain/main
anshumandas Jul 13, 2024
80a4999
interim commit for merging PRs
anshumandas Jul 13, 2024
688306c
Merge branch 'main' of https://github.com/anshumandas/get-flutter-fire
anshumandas Jul 13, 2024
038adb5
Fix null check error in ImagePickerButton and improve null handling i…
neminsheth Jul 13, 2024
50e9bdb
fix: bottom navigation current index
Jul 14, 2024
c1fedc4
fix: handled bottom nav index for path & query parameters
Jul 14, 2024
ad6278c
added image picker
Aas11223 Jul 15, 2024
4125c29
change readme
Aas11223 Jul 15, 2024
08eba7d
TODO 14
ved-gg Jul 15, 2024
0d780ef
added check if the path mentioned is for bottom navigation
Jul 15, 2024
e4bcbf8
Merge branch 'anshumandas:main' into main
ved-gg Jul 15, 2024
1c76904
added ClientID as environment variable
ved-gg Jul 15, 2024
345e779
Merge branch 'main' of github.com:vedantbhawnani/get-flutter-fire
ved-gg Jul 16, 2024
10f710b
feature/phone verification
ved-gg Jul 17, 2024
1180864
using full path for bottom navigation
Jul 17, 2024
6d64d12
update/phone auth screens UI
ved-gg Jul 17, 2024
b99f3fd
Added Search Bar (Toggle Button for phones) on Top Center with Title
Aas11223 Jul 19, 2024
134d8a4
Removed firebase.json
neminsheth Jul 19, 2024
47427f9
Merge branch 'main' into feature/reset-password-email-verification
neminsheth Jul 19, 2024
1dee2ce
fixed async bug
anshumandas Jul 20, 2024
4882d04
Merge pull request #3 from neminsheth/feature/reset-password-email-ve…
anshumandas Jul 20, 2024
8b3ecff
Merge pull request #6 from HardikSJain/bug-fix
anshumandas Jul 20, 2024
aa7f6fa
Merge pull request #13 from Aastha-Gadhvi/main
anshumandas Jul 20, 2024
170bedb
Revert "Bugs, ToDo 13.3"
anshumandas Jul 20, 2024
47dc1d1
Merge pull request #15 from anshumandas/revert-13-main
anshumandas Jul 20, 2024
a5a56a5
Revert "Feature/reset password email verification"
anshumandas Jul 20, 2024
626531f
Merge pull request #16 from anshumandas/revert-3-feature/reset-passwo…
anshumandas Jul 20, 2024
5defcab
Merge branch 'main' into main
ved-gg Jul 20, 2024
1d51db9
resolved conflicts
ved-gg Jul 20, 2024
2d10cc6
fix/sign up method
ved-gg Jul 21, 2024
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
9 changes: 9 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@ migrate_working_dir/
.pub/
/build/

node_modules
android/app/google-services.json

# Symbolication related
app.*.symbols

Expand Down Expand Up @@ -61,10 +64,15 @@ android/app/src/main/res/values-night/styles.xml
android/app/src/profile/AndroidManifest.xml
android/gradle/wrapper/gradle-wrapper.properties
ios/.gitignore
ios/Flutter/flutter_export_environment.sh
ios/Flutter/Generated.xcconfig
ios/Runner/GeneratedPluginRegistrant.h
ios/Runner/GeneratedPluginRegistrant.m
ios/Flutter/Debug.xcconfig
ios/Flutter/Release.xcconfig
ios/Runner/AppDelegate.swift
ios/Runner/Runner-Bridging-Header.h
ios/Runner/GoogleService-Info.plist
ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json
ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png
ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png
Expand Down Expand Up @@ -110,6 +118,7 @@ macos/.gitignore
macos/Flutter/Flutter-Debug.xcconfig
macos/Flutter/Flutter-Release.xcconfig
macos/Flutter/GeneratedPluginRegistrant.swift
macos/Flutter/ephemeral/
macos/Runner/AppDelegate.swift
macos/Runner/DebugProfile.entitlements
macos/Runner/MainFlutterWindow.swift
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ Step 7: Additional Auth flow items
* Phone Auth on Web has a ReCaptcha already [https://firebase.flutter.dev/docs/auth/phone/]. Tried to use that library but it is very cryptic.
* Use the following instead [https://stackoverflow.com/questions/60675575/how-to-implement-recaptcha-into-a-flutter-app] or [https://medium.com/cloudcraftz/securing-your-flutter-web-app-with-google-recaptcha-b556c567f409] or [https://pub.dev/packages/g_recaptcha_v3]
3. TODO: Ensure Reset Password has Email verification
4. TODO: Add Phone verification [https://firebase.google.com/docs/auth/flutter/phone-auth]
4. Added Phone verification [https://firebase.google.com/docs/auth/flutter/phone-auth]
* See [https://github.com/firebase/flutterfire/issues/4189].
5. TODO: Add 2FA with SMS Pin. This screen is available in the Flutter Fire package

Expand Down
Binary file added assets/icons/google.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
16 changes: 16 additions & 0 deletions ios/Runner/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -52,4 +52,20 @@
<key>NSPhotoLibraryUsageDescription</key>
<string>Allow access to photo library</string>
</dict>
<!-- Put me in the [my_project]/ios/Runner/Info.plist file -->
<!-- Google Sign-in Section -->
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleTypeRole</key>
<string>Editor</string>
<key>CFBundleURLSchemes</key>
<array>
<!-- TODO Replace this value: -->
<!-- Copied from GoogleService-Info.plist key REVERSED_CLIENT_ID -->
<string>com.googleusercontent.apps.260821266676-n1dskq31gq05s8egsuemfl2slek3vd9b</string>
</array>
</dict>
</array>
<!-- End of the Google Sign-in Section -->
</plist>
275 changes: 275 additions & 0 deletions lib/app/modules/login/views/custom_login.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,275 @@
import 'dart:developer';

import 'package:flutter/material.dart';
import 'package:get/get.dart';
import '../../../../models/screens.dart';
import '../../../../services/auth_service.dart';

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

@override
Widget build(BuildContext context) {
final height = MediaQuery.of(context).size.height;
final width = MediaQuery.of(context).size.width;

final emailController = TextEditingController();
final passwordController = TextEditingController();

return Scaffold(
backgroundColor: Colors.grey[300],
body: SingleChildScrollView(
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
SizedBox(height: height * 0.02),
//logo
Image.asset(
'assets/icons/logo.png',
height: height * 0.25,
width: width * 0.25,
),

SizedBox(
height: height * 0.02,
),

// welcome back
const Text("You were missed! Welcome Back"),
SizedBox(height: height * 0.02),

//username textfield
InputWidget(
width: width,
emailController: emailController,
hintText: 'Email ID',
obscureText: false,
keyboardType: TextInputType.emailAddress,
),
SizedBox(height: height * 0.02),
//password textfield
InputWidget(
width: width,
emailController: passwordController,
hintText: 'Password',
obscureText: true,
),

//forgot password?
Padding(
padding: EdgeInsets.only(right: width * 0.055),
child: Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
TextButton(
onPressed: () {
TextEditingController resetController =
TextEditingController();
Get.defaultDialog(
title: "Reset Passsword",
content: Column(
children: [
const Text("Enter your Email-ID"),
InputWidget(
width: width,
emailController: resetController,
hintText: "Email",
obscureText: false),
],
),
actions: [
TextButton(
child: const Text("Cancel"),
onPressed: () {
Get.back();
},
),
TextButton(
child: const Text('Send Reset Link'),
onPressed: () async {
try {
await AuthService().resetPassword(
email: resetController.text.trim());
Get.snackbar('Password Reset',
'A password reset link has been sent to your email.');
Get.back(); // Close dialog using GetX
} catch (e) {
Get.snackbar(
'Error', 'Failed to send reset link.');
log("Error sending reset link: $e");
}
},
),
],
);
},
child: Text(
"Forgot Password?",
style: TextStyle(color: Colors.grey.shade600),
)),
],
),
),
//sign in button
GestureDetector(
onTap: () {
if (emailController.text.isEmpty ||
!emailController.text.contains('@')) {
Get.snackbar(
'Invalid Email',
"Please enter a valid email id.",
);
} else if (passwordController.text.isEmpty ||
passwordController.text.length < 6) {
Get.snackbar(
'Invalid Password',
"Please enter a password longer than 6 letters.",
);
} else if (emailController.text.isNotEmpty &&
passwordController.text.isNotEmpty) {
AuthService()
.login(emailController.text, passwordController.text);
}
},
child: Container(
padding: EdgeInsets.symmetric(horizontal: width * 0.05),
margin: EdgeInsets.symmetric(horizontal: width * 0.1),
height: height * 0.07,
width: width * 0.2,
decoration: BoxDecoration(
color: Colors.black,
borderRadius: BorderRadius.circular(10),
),
child: const Center(
child: Text("Sign In",
style: TextStyle(
color: Colors.white,
fontWeight: FontWeight.bold,
fontSize: 18))),
),
),

SizedBox(height: height * 0.05),

//or continue with
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
SizedBox(
width: width * 0.2,
child: Divider(
thickness: 0.5,
color: Colors.grey.shade900,
)),
SizedBox(
width: width * 0.05,
),
const Text("Or Continue with"),
SizedBox(
width: width * 0.05,
),
SizedBox(
width: width * 0.2,
child: Divider(
thickness: 0.5,
color: Colors.grey.shade900,
)),
],
),

SizedBox(height: height * 0.02),

//google sign in
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
GestureDetector(
onTap: () => AuthService().signInwithGoogle(),
child: Container(
padding: EdgeInsets.all(width * 0.03),
margin: EdgeInsets.symmetric(horizontal: width * 0.04),
decoration: BoxDecoration(
color: Colors.grey.shade200,
borderRadius: BorderRadius.circular(10),
),
child: Image.asset('assets/icons/google.png',
height: height * 0.045),
),
),
GestureDetector(
onTap: () =>
Get.rootDelegate.toNamed(Screen.MOBILEAUTH.route),
child: Container(
padding: EdgeInsets.all(width * 0.03),
margin: EdgeInsets.symmetric(horizontal: width * 0.04),
decoration: BoxDecoration(
color: Colors.grey.shade200,
borderRadius: BorderRadius.circular(10),
),
child: Icon(Icons.phone, size: height * 0.045),
),
),
],
),

SizedBox(height: height * 0.02),

//register now / sign up now
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const Text('New user?'),
GestureDetector(
onTap: () {
Get.rootDelegate.toNamed(Screen.SIGNUP.route);
},
child: const Text(' Register now',
style: TextStyle(color: Colors.blue))),
],
),
const SizedBox(
height: 40,
),
],
),
),
),
);
}
}

class InputWidget extends StatelessWidget {
const InputWidget(
{super.key,
required this.width,
required this.emailController,
required this.hintText,
required this.obscureText,
this.keyboardType});

final double width;
final TextEditingController emailController;
final String hintText;
final bool obscureText;
final TextInputType? keyboardType;

@override
Widget build(BuildContext context) {
return Padding(
padding: EdgeInsets.symmetric(horizontal: width * 0.08),
child: TextField(
controller: emailController,
decoration: InputDecoration(
enabledBorder: const OutlineInputBorder(
borderSide: BorderSide(color: Colors.white)),
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(color: Colors.grey.shade400)),
fillColor: Colors.grey.shade200,
filled: true,
hintText: hintText),
obscureText: obscureText,
),
);
}
}
Loading