#I've been following a youtube project for twitter clone and I get error when putting _userFromFirebaseUser in map();#
##I get error at time 13:29, here is the link. https://www.youtube.com/watch?v=YI7avcWI3aQ&t=919s ##
##The error that I received at the terminal is Launching lib\main.dart on sdk gphone x86 arm in debug mode...
lib\main.dart:1
lib/services/auth/auth.dart:13:40: Error: The argument type 'UserModel? Function(User)' can't be assigned to the parameter type 'UserModel Function(User?)' because 'UserModel?' is nullable and 'UserModel' isn't.
'UserModel' is from 'package:twitterclone/models/users.dart' ('lib/models/users.dart').
'User' is from 'package:firebase_auth/firebase_auth.dart' ('../../AppData/Local/Pub/Cache/hosted/pub.dartlang.org/firebase_auth-1.0.1/lib/firebase_auth.dart').
return auth.authStateChanges().map(_userFromFirebaseUser);
The code and the directories
-users.dart
class UserModel {
final String id;
UserModel({required this.id});
}
-auth.dart
import 'package:firebase_auth/firebase_auth.dart';
import 'package:twitterclone/models/users.dart';
class AuthService {
FirebaseAuth auth = FirebaseAuth.instance;
UserModel? _userFromFirebaseUser(User user) {
// ignore: unnecessary_null_comparison
return user != null ? UserModel(id: user.uid) : null;
}
Stream<UserModel> get user {
return auth.authStateChanges().map(_userFromFirebaseUser);
}
Future<void> signUp(email, password) async {
try {
User user = (await auth.createUserWithEmailAndPassword(
email: email, password: password)) as User;
_userFromFirebaseUser(user);
} on FirebaseAuthException catch (e) {
if (e.code == 'user-not-found') {
print('No user found for that email.');
} else if (e.code == 'wrong-password') {
print('Wrong password provided for that user.');
}
} catch (e) {
print(e);
}
}
Future<void> signIn(email, password) async {
try {
User user = (await auth.signInWithEmailAndPassword(
email: email, password: password)) as User;
_userFromFirebaseUser(user);
} on FirebaseAuthException catch (e) {
print(e);
} catch (e) {
print(e);
}
}
}
In
UserModel? _userFromFirebaseUser(User user) {
// ignore: unnecessary_null_comparison
return user != null ? UserModel(id: user.uid) : null;
}
Since UserModel is nullable, change the argument to be nullable also
UserModel? _userFromFirebaseUser(User? user) ...
Use This code:-
Stream<UserList?> get user {
return _auth
.authStateChanges()
.map((User? user) => _userFromFirebase(user!));
}
*UserList is class,
null safety!
Related
I am unable to register an user from my app written in Flutter. I am also unable to get some form for error message. I can debug and see my createUser function is called and the arguments looks good. Nothing happens after I call "FirebaseAuth.instance.createUserWithEmailAndPassword". No exception and nothing is printed in the FireBase emulator console. What am I missing here? Here is what I got:
Emulator:
Running on 127.0.0.1:9099
main.dart:
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp(options: DefaultFirebaseOptions.currentPlatform,);
try {
await FirebaseAuth.instance.useAuthEmulator('localhost', 9099);
} catch (e) {
// ignore: avoid_print
print(e);
}
runApp(
MaterialApp(
title: "Foo",
home: buildContent(),
),
);
}
Registration function:
void createUser() async {
print("createUser()");
try {
final credential = await FirebaseAuth.instance.createUserWithEmailAndPassword(
email: nameController.text,
password: passwordController.text,
);
//final credential = await FirebaseAuth.instance.createUserWithEmailAndPassword(email: nameController.text, password: passwordController.text);
} on FirebaseAuthException catch (e) {
if (e.code == 'weak-password') {
print('The password provided is too weak.');
} else if (e.code == 'email-already-in-use') {
print('The account already exists for that email.');
}
} catch (e) {
print(e);
}
}
Edit:
I keep getting this message when i call "createUserWithEmailAndPassword"
W/System (26859): Ignoring header X-Firebase-Locale because its value was null.
In your createUser() Function i think you're sending empty values to firebase
request parameters like this and try it again
void createUser(String name, String Password) async {
print("createUser()");
try {
final credential = await FirebaseAuth.instance.createUserWithEmailAndPassword(
email: name,
password: password,
);
print("User Created Success);
//final credential = await FirebaseAuth.instance.createUserWithEmailAndPassword(email: nameController.text, password: passwordController.text);
} on FirebaseAuthException catch (e) {
if (e.code == 'weak-password') {
print('The password provided is too weak.');
} else if (e.code == 'email-already-in-use') {
print('The account already exists for that email.');
}
} catch (e) {
print(e);
}
}
So after some trail and error I ended up adding:
android:usesCleartextTraffic="true"
To the manifest file:
...\my_project\android\app\src\main\AndroidManifest.xml
I am not sure I like the "fix" as I think the requests are sent unencrypted. A google search gives me this description:
Android 6.0 introduced the useCleartextTraffic attribute under application element in android manifest. The default value in Android P is “false”. Setting this to true indicates that the app intends to use clear network traffic
auth.dart
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/foundation.dart';
import 'package:lewandowski/models/bro.dart';
import '../shared/database.dart';
class AuthService{
// method to sign in anon
final FirebaseAuth _auth = FirebaseAuth.instance;
Bro? get bro => null;
// create an object based on firebaseuser
Bro? _userfromFirebaseUser(Bro? user){
return User != null ? Bro(uid:user!.uid) : null;
}
// change user stream
Stream<Bro?> get user {
return _auth.authStateChanges().map(_userfromFirebaseUser);
}
Future signAnon() async {
try {
UserCredential result = await _auth.signInAnonymously();
User? user = result.user;
return user;
}
catch (e) {
print(e.toString());
return null;
}
}
Future signInWithEmailandPassword(String email, String password) async{
try {
UserCredential result = await _auth.signInWithEmailAndPassword(email: email, password: password);
User? user = result.user;
return _userfromFirebaseUser(user as Bro);
}
catch(e){
print(e.toString());
}
}// method to sign in with email and password
// method to sign up with email and password
Future registerWithEmailandPassword(String email, String password) async{
try {
UserCredential result = await _auth.createUserWithEmailAndPassword(
email: email, password: password);
User? user = result.user;
// use of brewscollection
await DatabaseService(uid: user!.uid).updateDatabase('0', 'new user', 100);
return _userfromFirebaseUser(user as Bro);
}
catch(e){
print(e.toString());
}
}
//method to sign out
Future signOut() async{
try{
return await _auth.signOut();
}
catch(e){
print(e.toString());
}
return null;
}
}
error on:
Stream<Bro?> get user {
return _auth.authStateChanges().map(_userfromFirebaseUser);
says:The argument type 'Bro? Function(Bro?)' can't be assigned to the parameter type 'Bro? Function(User?)'.
Running Gradle task 'assembleDebug'...
lib/services/auth.dart:20:41: Error: The argument type 'Bro? Function(Bro?)' can't be assigned to the parameter type 'Bro? Function(User?)'.
- 'Bro' is from 'package:lewandowski/models/bro.dart' ('lib/models/bro.dart').
- 'User' is from 'package:firebase_auth/firebase_auth.dart' ('../flutter/.pub-cache/hosted/pub.dartlang.org/firebase_auth-3.9.0/lib/firebase_auth.dart').
return _auth.authStateChanges().map(_userfromFirebaseUser);
^
FAILURE: Build failed with an exception.
The value from _auth.authStateChanges() will be User But you are expecting Bro.
Try changing the function parameter type from Bro? to User?
Bro? _userfromFirebaseUser(User? user){
return user != null ? Bro(uid:user!.uid) : null;
}
hi every one I'm trying making my app with flutter . it is contains a sign up page so I write the code and I'm retrieving an information from the firebase after I upload it .
the below code is the sign up code
UserModel? _userFromFirebaseUser(User userCredential) {
return userCredential != null
? UserModel(
id: userCredential.uid,
bannerImageUrl: '',
name: '',
email: '',
profileImageUrl: '')
: null;
}
Stream<UserModel?> get userCredential {
return auth
.authStateChanges()
.map((userCredential) => _userFromFirebaseUser(userCredential!));
}
Future SignUp(email, password) async {
var formdata = formstate.currentState;
if (formdata!.validate()) {
print("valid");
formdata.save();
try {
UserCredential userCredential =
(await auth.createUserWithEmailAndPassword(
email: myemail!, password: mypassword!));
FirebaseFirestore.instance
.collection('Users')
.doc(userCredential.user!.uid)
.set({'name': email, 'email': email});
_userFromFirebaseUser(userCredential.user);
return userCredential;
} on FirebaseAuthException catch (e) {
if (e.code == 'weak-password') {
Navigator.of(context).pop();
print('The password provided is too weak.');
} else if (e.code == 'email-already-in-use') {
Navigator.of(context).pop();
print('The account already exists for that email.');
}
} catch (e) {
print(e);
}
} else {}
}
and the red line appears on this line _userFromFirebaseUser(userCredential.user); as it is appears in the picture . please help me
userCredential.user is User? not User
change the method parameter
UserModel? _userFromFirebaseUser(User? userCredential) {
return ....
}
I am getting red line on auth.authStateChanges(),
Error says : A value of type 'Stream<User?>' can't be returned from the function 'user' because it has a return type of 'Stream?'.
class Auth {
final FirebaseAuth auth;
Auth({required this.auth});
Stream<User>? get user => auth.authStateChanges(); <-- here
Update now i get this error:
Future<String?> createAccount({required String email, required String password}) async {
try {
await auth.createUserWithEmailAndPassword( <-- here **auth**
email: email.trim(),
password: password.trim(),
);
return "Success";
} on FirebaseAuthException catch (e) {
return e.message;
} catch (e) {
rethrow;
}
}
Here is your updated class
import 'package:firebase_auth/firebase_auth.dart';
class Auth {
final FirebaseAuth auth;
Auth({required this.auth});
Stream<User?> get user => auth.authStateChanges();
Future<String?> createAccount({required String email, required String password}) async {
try {
await FirebaseAuth.instance.createUserWithEmailAndPassword(
email: email.trim(),
password: password.trim(),
);
return "Success";
} on FirebaseAuthException catch (e) {
return e.message;
} catch (e) {
rethrow;
}
}
}
I am getting the following error in flutter.
UserModel is a class
class UserModel {
final String uid;
UserModel({this.uid});
}
And the code where this error is coming up is
Stream<UserModel> get user {
return _auth.authStateChanges()
.map(_userFromFirebaseUser);
}
Complete code:
class AuthService {
final FirebaseAuth _auth = FirebaseAuth.instance;
UserModel? _userFromFirebaseUser(User? user) {
return user != null ? UserModel(uid: user.uid) : null;
}
Stream<UserModel> get user {
return _auth.authStateChanges()
.map(_userFromFirebaseUser);
}
Future signInAnon() async {
try {
UserCredential result = await _auth.signInAnonymously();
User user = result.user!;
return _userFromFirebaseUser(user);
} catch (e) {
print(e.toString());
return null;
}
}
Future signInWithEmailAndPassword( String email, String password) async {
try {
UserCredential result = await _auth.signInWithEmailAndPassword(email: email, password: password);
User user = result.user!;
return _userFromFirebaseUser(user);
} catch(e){
print(e.toString());
return null;
}
}
Future signUpWithEmailAndPassword( String email, String password) async {
try {
UserCredential result = await _auth.createUserWithEmailAndPassword(email: email, password: password);
User user = result.user!;
return _userFromFirebaseUser(user);
} catch(e){
print(e.toString());
return null;
}
}
Future signOut() async {
try {
return await _auth.signOut();
} catch (e){
print(e.toString());
return null;
}
}
}
This is happening because your _userFromFirebaseUser is defined something like this,
UserModel? _userFromFirebaseUser(User? user) {
So this means that you are saying, your _userFromFirebaseUser might return a UserModel or might return a null.
One way to fix this is to make your getter return Stream<UserModel?> instead of Stream<UserModel>.
Stream<UserModel?> get user {
return _auth.authStateChanges()
.map(_userFromFirebaseUser);
}
Now your getter might return a UserModel or it might return a null.
I had the same problem and I'm glad I found the solution :
UserModel _userFromFirebase (User? user){
return UserModel(uid: user!.uid);
}
Stream<UserModel> get user{
return _auth.authStateChanges().map(_userFromFirebase);
}
and if _userFromFirebase appears error use:
_userFromFirebase(user.user) ;