bizz84 / firebase_auth_demo_flutter Goto Github PK
View Code? Open in Web Editor NEWReference Authentication Flow with Flutter & Firebase
Home Page: https://codewithandrea.com/
License: MIT License
Reference Authentication Flow with Flutter & Firebase
Home Page: https://codewithandrea.com/
License: MIT License
So I am not exactly a complete newcomer to Flutter, but I do have many gaps in my understanding of how all of the pieces fit together. Regardless, I am trying to increase the complexity of my apps and I liked the work you have done in this repo and wanted to learn from you.
I have run into an issue which is outside of anything I have previously encountered in Flutter and so far my Google searches to resolve the problem have not been very helpful.
SUMMARY: When I try to run your app with only the minimal changes required to allow it to connect to my instance of Firebase, it flashes a white screen for a brief moment and then exits. I am seeing the same behavior on my Android emulator and my physical Android device (I have not attempted on ios). The following are the last 4 messages displayed in the debug console each time I attempt to run:
I am assuming this problem is related to how my environment is setup to handle plugins and I am totally unfamiliar with how plug ins are setup/developed/deployed.
I have done the normal flutter clean / doctor / build routine to see if that would help.
I would appreciate any insight or suggestions you may have.
Flutter: 1.12.13_hotfix.9 - stable channel
Windows 10 development environment
I'm not getting the alert of the PlatformException when user get ERROR_WRONG_PASSWORD, ERROR_TOO_MANY_REQUESTS, etc. Does anyone knows how to fix it?
Hello,
Thanks for the article.. I like the mock service but I don't want to use it now.. Do I still need the adapter class?
Thanks
I am getting error missing google auth token, what to do next. I am stuck here.
Thanks for a great demo! I'm running into an issue trying to incorporate navigation after the user has successfully logged in.
When I call Navigator.push(context, <any_route>)
it causes the LandingPage
widget tree to be rebuilt, which then recreates the StreamBuilder<User>
. Upon successful login, I changed your code to return an AuthenticatedLandingPage
widget instead of HomePage
so I can load the user's profile before displaying the home page. Unfortunately, every time I navigate it reloads their profile due to the rebuilding.
Do you have any established best practices for dealing with loading data like this after logging in? I know the build
method can be called at anytime it just seems like using StreamBuilder
inside of build
results in lots of recreations of the User
stream (and any subsequent data streams dependent on the User
like in my case UserProfile
).
// LandingPage.dart
class LandingPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return StreamBuilder<FirebaseUser>(
stream: FirebaseAuth.instance.onAuthStateChanged,
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.active) {
if (!snapshot.hasData) {
return AuthSplashPage();
}
final user = snapshot.data;
return Provider<FirebaseUser>.value(
value: user,
child: const AuthenticatedLandingPage(),
);
}
return _loadingScreen("Authenticating");
},
);
}
}
class AuthenticatedLandingPage extends StatelessWidget {
const AuthenticatedLandingPage();
@override
Widget build(BuildContext context) {
// this gets rebuilt every time we navigate in the app
final user = Provider.of<FirebaseUser>(context);
final userService = Provider.of<UserService>(context);
return StreamBuilder<UserProfile>(
stream: userService.streamProfile(user.uid), // calls Firestore.instance.collection("user_profile").document(user.uid).snapshots()
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.active) {
if (!snapshot.hasData) {
return OnboardingSplashPage();
}
final profile = snapshot.data;
return Provider<UserProfile>.value(
value: profile,
child: const HomePage(),
);
}
return _loadingScreen("Loading profile");
},
);
}
}
Thanks!
I think it would be helpful to see how to properly allow the user to read/write from a firebase database once the user has been authenticated.
Taken from FirebaseUser.linkWithCredential()
:
Associates a user account from a third-party identity provider with this user and returns additional identity provider data.
This feature can be used to link additional providers to an existing Firebase user.
List of supported providers:
When using the "Signin with email link", I do receive the link in my email, when I click it I see:
Not sure what I'm looking for or what code needs to be updated.
When I add the param ?d=1
per instructions here: https://firebase.google.com/docs/dynamic-links/debug, I see that there is no error reported:
Thanks for making this project, it's very good.
Hello,
Thanks for the article... How do you add multiple provider,,, Suppose , I have another provider name shopping that I also need down stream...
Thanks
error
Exception has occurred. PlatformException (PlatformException(sign_in_failed, com.google.android.gms.common.api.ApiException: 12500: , null))
please resolve this problem
I am trying to get the 'Sign in aborted by user.' dialog box to show when I close the Google Sign In. Right now when I click close the app crashes and this is what appears:
Exception has occurred.
PlatformException (PlatformException(sign_in_canceled, com.google.GIDSignIn, The user canceled the sign-in flow.))
The line appears on the following line of code in the Auth.dart file:
GoogleSignInAccount googleUser = await googleSignIn.signIn();
Just to test the functionality of the dialog box, I changed the if statement in auth.dart from:
if (googleUser != null)
to
if (googleUser == null)
This results in the dialog box appearing. So throwing the PlatformException must be working correctly. It seems like the problem is that the app crashes before the program checks if the user is null.
I have even tried directly catching the error like this:
GoogleSignInAccount googleUser;
try {
googleUser = await googleSignIn.signIn();
} catch (e) {
throw PlatformException(
code: "ERROR_ABORTED_BY_USER",
message: 'Sign in aborted by user.',
);
}
I think that googleSignIn.signIn() might be returning an exception instead of null, but I have the same version as the videos.
App has been in installation state without error
Hi @bizz84,
Thank you for your work, this auth implementation with Provider looks neat !
I'd love to use it in my project and I was wondering if you've planned to publish a standalone library for ease of use ?
J.
I clone this repo for one of my firebase project it works perfect but after success-full login i can't find a navigation in your code can you please help me with that. I get stuck from the in the flow after auth_widget.dart
file.
I download the code and run into simulator one strange behaviour that i can't understand. If I uninstall the app without logout from the simulator, run flutter clean and run the code again the app start with previous login info i try to track this but i can't find this can you help me because my whole app is depending on your login flow and now i don't want to change this login part.
The current Regex only allows one dot (.
) following the @
symbol.
Thanks for the articles..
This is not a bug but I am not sure how to ask the question,,,
I am not using BLOC pattern, It is too complex for my project .. Do you have a similar article using just provider pattern..
Thanks
Thanks for sharing all this work on this auth demo. I have learned a lot from it and your Udemy course.
May I suggest what would be a really useful feature. A lot of apps have only certain areas require authentication. Instead of requiring authentication upfront, the demo could allow only specified pages to require an authenticated user. So users could install, try, and explore the app before committing to signing in. A smoother onboarding experience with less friction. Of course the developer could still config the app to require login at the beginning.
Alvin
You mention in the readme, that we have to download and install a google-services.json, but you don't mention, where it can be downloaded. Could you add that info, please? Thank you!
Reason: I think that somebody, who comes to this site directly and does not know about Firebase or your course or whatever, should get all information needed to be well-informed what to do. In this case it would help to make things very clear, when sth like "Download google-services.json from your firebase account that is needed for this project."
This is even helpful for people, who already worked through your tutorial and come back to it sometimes later. Thank you!
This was reported by a student of my course.
Reproduction steps
run the App on iOs simulator or real iOS device.
click on sign in with google button.
alert will popup "YOUR_APP_NAME Wants to Use 'google.com' to Sign In (Continue, Cancel)".
NOW lock the iOS device by pressing the device side button.
now unlock the iOS device.
you will notice that the spinner still working, and nothing you can do.
you must hot restart the app on simulator, or kill the app in real device.
you can use AppLifecycleState.resumed to reset variable.
but if you clicked on the button again you will get this error:
flutter: PlatformException(concurrent-requests, Concurrent requests to account signin, null)
flutter: message: PlatformException(concurrent-requests, Concurrent requests to account signin, null)
@bizz84 well I receive this error every time I try to signup while trying to implement your solution working only with FirebaseAuthService()
, and also getting rid of the dispose()
method:
E/flutter (32103): [ERROR:flutter/lib/ui/ui_dart_state.cc(148)] Unhandled Exception: A SignInModel was used after being disposed.
E/flutter (32103): Once you have called dispose() on a SignInModel, it can no longer be used.
E/flutter (32103): #0 _SignInModel&Object&EmailAndPasswordValidators&ChangeNotifier._debugAssertNotDisposed. (package:flutter/src/foundation/change_notifier.dart:105:9)
E/flutter (32103): #1 _SignInModel&Object&EmailAndPasswordValidators&ChangeNotifier._debugAssertNotDisposed (package:flutter/src/foundation/change_notifier.dart:111:6)
E/flutter (32103): #2 _SignInModel&Object&EmailAndPasswordValidators&ChangeNotifier.notifyListeners (package:flutter/src/foundation/change_notifier.dart:200:12)
E/flutter (32103): #3 SignInModel.updateWith (package:firebase_auth_demo_flutter/app/sign_in/sign_in_model.dart:77:5)
E/flutter (32103): #4 SignInModel.submit (package:firebase_auth_demo_flutter/app/sign_in/sign_in_model.dart:47:7)
E/flutter (32103):
Originally posted by @MRANASSPRO in #19 (comment)
Solution:
void validateAndSubmit() async {
if (validateAndSave()) {
try {
FirebaseUser user = (await FirebaseAuth.instance
.signInWithEmailAndPassword(email: _email, password: _password))
.user;
print('Signed in: ${user.uid}');
} catch (e) {
print('Error: $e');
}
}
}
I'm following your provider tutorial and I can't find the initial-setup
branch.
Thanks for sharing the repository for others to refer to. Had a couple of suggestions that could be looked into
Andrea,
Do you have any plans on updating this project to work in the latest (null safety) versions of Flutter/Dart?
Thanks.
Thank you for sharing this amazing repo.
Just a quick request/question.
It can't build the app now :(
Error Code
FolderOfTheApp/ios/Pods/GoogleDataTransport/GoogleDataTransport/GDTLibrary/GDTStorage.m:122:41: error: no known class method for selector 'archivedDataWithRootObject:requiringSecureCoding:error:'
NSData *data = [NSKeyedArchiver archivedDataWithRootObject:self
Flutter Doctor
`[✓] Flutter (Channel stable, v1.9.1+hotfix.2, on Mac OS X 10.13.2 17C88, locale en-TR)
• Flutter version 1.9.1+hotfix.2 at /Users/yasinarik/Documents/flutter
• Framework revision 2d2a1ffec9 (9 days ago), 2019-09-06 18:39:49 -0700
• Engine revision b863200c37
• Dart version 2.5.0
[✓] Android toolchain - develop for Android devices (Android SDK version 29.0.2)
• Android SDK at /Users/yasinarik/Library/Android/sdk
• Android NDK location not configured (optional; useful for native profiling support)
• Platform android-29, build-tools 29.0.2
• Java binary at: /Applications/Android Studio.app/Contents/jre/jdk/Contents/Home/bin/java
• Java version OpenJDK Runtime Environment (build 1.8.0_202-release-1483-b49-5587405)
• All Android licenses accepted.
[✓] Xcode - develop for iOS and macOS (Xcode 9.4.1)
• Xcode at /Applications/Xcode.app/Contents/Developer
• Xcode 9.4.1, Build version 9F2000
• CocoaPods version 1.6.1
[✓] Android Studio (version 3.5)
• Android Studio at /Applications/Android Studio.app/Contents
• Flutter plugin version 38.2.3
• Dart plugin version 191.8423
• Java version OpenJDK Runtime Environment (build 1.8.0_202-release-1483-b49-5587405)
[✓] VS Code (version 1.38.1)
• VS Code at /Applications/Visual Studio Code.app/Contents
• Flutter extension version 3.4.1
[✓] Connected device (1 available)
• iPhone 8 • C0922638-B946-421B-BE90-C8D92A6B475F • ios • iOS 11.4 (simulator)
• No issues found!`
Great project, thanks!
However when I tried to use this code in a freshly created project using Flutter 1.17.1 (stable) it throws the following exception whenever I tap "Sign in with Google". It also happens when signing out.
Debug console:
W/FlutterActivity(26934): Tried to automatically register plugins with FlutterEngine (io.flutter.embedding.engine.FlutterEngine@d756c5d) but could not find and invoke the GeneratedPluginRegistrant.
Exception:
MissingPluginException (MissingPluginException(No implementation found for method init on channel plugins.flutter.io/google_sign_in))
When I use the project as-is from github it works perfectly, but thought you'd like to know there may be an issue with new projects going forward, at least on Android. It appears they recently changed how plugins are embedded, which I suspect is related to this regression.
To reproduce:
flutter create my_project
lib
, assets
, and pubspec.yaml
with yours (but with firebase_auth: ^0.16.0
and google_sign_in: ^4.4.4
)Expected: Should sign in like the official github project
Actual: Throws above error/exception
The exception is being triggered on the following line in firebase_auth_service.dart
, specifically in the signIn()
function:
final GoogleSignInAccount googleUser = await googleSignIn.signIn();
I'm continuing to troubleshoot and will update if I find anything, but wanted to let you know.
i tried to follow your video course , i am failed to get it working on iOS. in android it's working correctly as expected.
this is the error message in the console.
Falling back to storing access token in NSUserDefaults because of simulator bug
I've been through your Udemy Flutter & Firebase course. I wanted to study this demo for additional insights. Thank you for making it available to all.
I'm seeing a hitch in iOS. The device screen (in my simulator) does not get past a blank white screen. There is no widget tree in the Flutter Inspector in IntelliJ and no error output. Running it in Xcode, this one bit of output seems especially suspicious.
Unhandled Exception: MissingPluginException
(No implementation found for method isAvailable on channel dev.gilder.tom/apple_sign_in)
There is a lot more to that output (I'll post here if you want to see it) but I thought I'd start by asking if this one line could point to the reason for the blank white screen?
Google sign in works on Android but crashes the app when clicking on Google sign in button. App just closes. I've taken your Udemy course and I've set up Google sign in on iOS without any issues following your course material. Tried a whole bunch of different things but can't seem to figure it out. Any help would be appreciated. Here is the error log:
Performing hot restart...
Syncing files to device iPhone 11...
Restarted application in 1,369ms.
Lost connection to device.
*** First throw call stack:
(
0 CoreFoundation 0x00007fff23e3cf0e __exceptionPreprocess + 350
1 libobjc.A.dylib 0x00007fff50ba89b2 objc_exception_throw + 48
2 CoreFoundation 0x00007fff23e3cd4c +[NSException raise:format:] + 188
3 Runner 0x00000001039f3c92 -[GIDSignIn signInWithOptions:] + 276
4 Runner 0x00000001039f35c7 -[GIDSignIn signIn] + 64
5 Runner 0x0000000103a0d5d8 -[FLTGoogleSignInPlugin handleMethodCall:result:] + 2392
6 Flutter 0x00000001040749df __45-[FlutterMethodChannel setMethodCallHandler:]_block_invoke + 104
7 Flutter 0x0000000104003622 _ZNK7flutt<…>
Hi,
i changed a little bit in your project to get only the mock service working. But, after that, the snapshot.connectionState is always waiting. Below some code:
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MultiProvider(
providers: <SingleChildCloneableWidget>[
Provider<AuthService>(
builder: (_) => AuthServiceAdapter(),
dispose: (_, AuthService authService) => authService.dispose(),
),
Provider<EmailSecureStore>(
builder: (_) => EmailSecureStore(),
),
],
child: MaterialApp(
theme: ThemeData(
primarySwatch: Colors.indigo,
),
home: LandingPage(),
),
);
}
}
AuthServiceAdapter.dart
class AuthServiceAdapter implements AuthService {
AuthServiceAdapter() {
_setup();
}
final JupiterAuthService _jupiterAuthService = JupiterAuthService();
// Value notifier used to switch between [FirebaseAuthService] and [JupiterAuthService]
ValueNotifier<AuthServiceType> authServiceTypeNotifier = ValueNotifier<AuthServiceType>(AuthServiceType.jupiter);
AuthServiceType get authServiceType => authServiceTypeNotifier.value;
AuthService get authService => _jupiterAuthService;
StreamSubscription<User> _jupiterAuthSubscription;
void _setup() {
// Observable<User>.merge was considered here, but we need more fine grained control to ensure
// that only events from the currently active service are processed
_jupiterAuthSubscription = _jupiterAuthService.onAuthStateChanged.listen((User user) {
if (authServiceType == AuthServiceType.jupiter) {
_onAuthStateChangedController.add(user);
}
}, onError: (dynamic error) {
if (authServiceType == AuthServiceType.jupiter) {
_onAuthStateChangedController.addError(error);
}
});
}
can you tell me the error?
Thanks
Unlike the current implementation, sign_in_with_apple supports more than just iOS. This is useful if your user has signed up with apple before on your website or another phone and has switched to android.
The package has also been recently marked as a Flutter favorite on pub.dev.
The FirebaseEmailLinkHandler
class needs to be revisited.
And iOS builds require this PR, which is not yet merged in the main repo:
Hello, I have a problem when clicking on "Connect with google"
I have the following error:
Unhandled Exception: MissingPluginException(No implementation found for method init on channel plugins.flutter.io/google_sign_in
i have add a GoogleService-Info.plist in ios/runner
i have configured firestorefirebase but not ok...
you have a idea?
It's possible to adapt the app for going to new SignUp page after first login? and if user is signin go to homepage
List of providers supported by Firebase Auth:
Other authentication features:
Hi, after clicking the activation link in my email inside gmail , a dialog box is shown to ask if I want to open this link using a browser or my own app. I click on the icon of my own app, and instead of being direct to my already opened app ( the 1st one ), the device switch on the same app ( the 2nd one ) and lead me to the homepage where it shows all the button for the various login method.
I am having two my app of the same thing being turn on in my device and running concurrently. What is the problem here?
I am using Android in this test.
I followed the instructions for the setup, but when I try to build the app in android it gets stuck on "Installing build/app/outputs/apk/app.apk". You can see it try to open the app, but it immediately crashes. The last output of the debug console is "Built build/app/outputs/apk/debug/app-debug.apk.".
The iOS version runs fine.
The existing validator may be too restrictive:
^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+(\.[a-zA-Z0-9-]+){1,2}$
This article covers in great detail how to approach email validation:
https://dev.to/jerodsanto/there-s-only-one-way-to-validate-an-email-address-4i3k
If a client regex should be used, this would work better:
^\S+@\S+\.\S+$
This is because the Firebase password reset flow is done from a browser (outside the app).
When resetting the password, the user is allowed to choose a password of less than 8 characters (6 characters is currently the minimum in Firebase).
With the current validator, users would not be able to sign in with a password that has been reset and is less than 8 characters.
It'd be great if you could please demo Twitter Auth as well. Twitter Auth is quite useful for apps that target people in tech.
this error comes when I do a email password - signin or register
[it does log me in]
exception
E/flutter (22129): [ERROR:flutter/lib/ui/ui_dart_state.cc(157)] Unhandled Exception: Bad state: No element
[ ] E/flutter (22129): #0 List.last (dart:core-patch/growable_array.dart:227:5)
[ ] E/flutter (22129): #1 NavigatorState.pop (package:flutter/src/widgets/navigator.dart:2118:43)
[ ] E/flutter (22129): #2 _EmailPasswordSignInPageState._submit
(package:firebase_auth_demo_flutter/app/sign_in/email_password/email_password_sign_in_page.dart:80:20)
[ ] E/flutter (22129):
[ ] E/flutter (22129): #3 _InkResponseState._handleTap (package:flutter/src/material/ink_well.dart:706:14)
[ ] E/flutter (22129): #4 _InkResponseState.build. (package:flutter/src/material/ink_well.dart:789:36)
[ ] E/flutter (22129): #5 GestureRecognizer.invokeCallback (package:flutter/src/gestures/recognizer.dart:182:24)
[ ] E/flutter (22129): #6 TapGestureRecognizer.handleTapUp (package:flutter/src/gestures/tap.dart:486:11)
[ ] E/flutter (22129): #7 BaseTapGestureRecognizer._checkUp (package:flutter/src/gestures/tap.dart:264:5)
[ ] E/flutter (22129): #8 BaseTapGestureRecognizer.acceptGesture (package:flutter/src/gestures/tap.dart:236:7)
[ ] E/flutter (22129): #9 GestureArenaManager.sweep (package:flutter/src/gestures/arena.dart:156:27)
[ ] E/flutter (22129): #10 GestureBinding.handleEvent (package:flutter/src/gestures/binding.dart:222:20)
[ ] E/flutter (22129): #11 GestureBinding.dispatchEvent (package:flutter/src/gestures/binding.dart:198:22)
[ ] E/flutter (22129): #12 GestureBinding._handlePointerEvent (package:flutter/src/gestures/binding.dart:156:7)
[ ] E/flutter (22129): #13 GestureBinding._flushPointerEventQueue (package:flutter/src/gestures/binding.dart:102:7)
[ ] E/flutter (22129): #14 GestureBinding._handlePointerDataPacket (package:flutter/src/gestures/binding.dart:86:7)
[ ] E/flutter (22129): #15 _rootRunUnary (dart:async/zone.dart:1138:13)
[ ] E/flutter (22129): #16 _CustomZone.runUnary (dart:async/zone.dart:1031:19)
[ ] E/flutter (22129): #17 _CustomZone.runUnaryGuarded (dart:async/zone.dart:933:7)
[ ] E/flutter (22129): #18 _invoke1 (dart:ui/hooks.dart:273:10)
[ ] E/flutter (22129): #19 _dispatchPointerDataPacket (dart:ui/hooks.dart:182:5)
[ ] E/flutter (22129):
--
Thank you
Within your lib/common_widgets/platform_widget.dart
you test if the Platform.isIOS
, which is absolutely correct for testing the real Platform. But with the Flutter Inspector you can also change the platform to iOS to test the iOS interface on Android.
If you would change the line:
if(Platform.isIOS) {
to:
if(Platform.isIOS || Theme.of(context)?.platform == TargetPlatform.iOS) {
Then during debugging you can also test iOS styles on Android and visa versa. Without this change the AlertDialog is always the Material one. With the change, you will see the Cupertino dialog.
Hey
i Have the Following Error and Cannot find the Problem.
The argument type 'MaterialApp Function(BuildContext, AsyncSnapshot)' can't be assigned to the parameter type 'Widget Function(BuildContext, AsyncSnapshot)'.
Line 45 in Main.dart.
Do you have a Idea what is the Problem?
Best
Sebastian
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.