UserCredential in Firebase - firebase

I'm having an error with Firebase for the first time, and not sure why it keeps showing the error.
Error :
The name 'UserCredential' is defined in the libraries 'package:firebase/src/auth.dart (via package:firebase/firebase.dart)' and 'package:firebase_auth/firebase_auth.dart'.\nTry using 'as prefix' for one of the import directives, or hiding the name from all but one of the imports.
import 'package:firebase_auth/firebase_auth.dart';
class AuthService {
final FirebaseAuth _auth = FirebaseAuth.instance;
// Create user object based on FirebaseUser
CustomUsers _customModelForFirebaseUser(user) {
return user != null ? CustomUsers(uid: user.uid) : null;
}
// auth changed user stream
Stream<CustomUsers> get user {
return _auth.authStateChanges().map(_customModelForFirebaseUser);
}
//Signin Anon
Future signInAnon() async {
try {
UserCredential userCredential = await _auth.signInAnonymously();
CustomUsers user = userCredential.user;
print(_customModelForFirebaseUser(user));
} catch (e) {
print(e.toString());
return null;
}
}

The package have same class name, which causing packing to conflicts. Try to hide one of them like this
import 'package:firebase_auth/firebase_auth.dart' hide UserCredential;
For more explanation check out this webiste dart-flutter-how-to-solve-naming-conflict-or-ambiguous

Related

Error in FirebaseAuth while using Provider

I want to create an entering page with firebase_auth. I can sign in successfully but I can't log in. When I try to log in application doesn't give any error but it isn't pass the main page. Still it is in log in page. When I restart the debugging now it pass the main page. Can you see my code and help me?
Here is my auth service code
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import 'package:library_app/models/person.dart';
class FirebaseAuthService {
final FirebaseAuth _auth = FirebaseAuth.instance;
Person? _createPerson(User? user) {
return user == null ? null : Person.fromFirebaseUser(user);
}
Stream<Person?> get statusFollower {
return _auth.authStateChanges().map(_createPerson);
}
void createUserEmailAndPassword({
required String email,
required String password,
}) async {
try {
var _userCredential = await _auth.createUserWithEmailAndPassword(
email: email,
password: password,
);
_createPerson(_userCredential.user);
} catch (e) {
debugPrint(e.toString());
}
}
loginUserEmailAndPassword({
required String email,
required String password,
}) async {
try {
var _userCredential = await _auth.signInWithEmailAndPassword(
email: email,
password: password,
);
_createPerson(_userCredential.user);
} catch (e) {
debugPrint(e.toString());
}
}
void signOut() async {
await _auth.signOut();
}
}
And here is my orientation code
import 'package:flutter/cupertino.dart';
import 'package:library_app/models/person.dart';
import 'package:library_app/pages/error_page.dart';
import 'package:library_app/pages/loading_page.dart';
import 'package:library_app/pages/main_page.dart';
import 'package:library_app/pages/sign_in_page.dart';
import 'package:library_app/services/firebase_auth_service.dart';
import 'package:provider/provider.dart';
class OrientationSystem extends StatelessWidget {
const OrientationSystem({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
var _authService = Provider.of<FirebaseAuthService>(context, listen: false);
return StreamBuilder<Person?>(
stream: _authService.statusFollower,
builder: (context, stream) {
if (stream.connectionState == ConnectionState.waiting) {
return const LoadingPage();
}
if (stream.hasData) {
return const MainPage();
}
if (!stream.hasData) {
return const SigInPage();
} else {
return const ErrorPage();
}
},
);
}
}
what must I do?
please help...
You did not extend or used with ChangeNotifier class in the FirebaseAuthService construction. Also, you need to notifyListener() after doing the tasks or after updating data inside your FirebaseAuthService class so that your other classes may listen to the updated values.
However, please update your question to something like "Error in FirebaseAuth while using Provider". Make your question titles as much relevant as you can otherwise you might get ban by the system. This is a suggestion.

The getter 'uid' not defined

i'm trying to create a food track app on android studio, it's my first time and i'm working with firebase_auth 3.3.12. my code in the aut.dart is:
import 'package:firebase_auth/firebase_auth.dart';
import 'package:my_firstapp/models/user_model.dart';
class AuthService {
final FirebaseAuth _auth = FirebaseAuth.instance;
AuthService();
// create user object based on FirebaseUser.
UserModel _userFromUser(User) {
return user != null ? UserModel(uid: user.uid) : null;
}
// auth change user stream
Stream<UserModel> get user {
return _auth.authStateChanges()
.map(_userFromUser);
}
Future<UserModel> getUser() async {
User user = await _auth.currentUser();
return _userFromUser(user);
}
// sign in with email and password
Future signInWithEmailAndPassword(String email, String password) async {
try {
UserCredential result = await _auth.signInWithEmailAndPassword(email: email, password: password);
User user = result.user;
return _userFromUser(user);
} catch(e) {
print(e.toString());
return null;
}
}
// 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;
// create a new user document in database
return _userFromUser(user);
} catch(e) {
print(e.toString());
return null;
}
}
// sign out
Future signOut() async {
try {
return await _auth.signOut();
} catch(e){
print(e.toString());
return null;
}
}
}
However i'm getting 2 errors:
-The getter 'uid' isn't defined for the type 'Stream';
-The expression "await _auth.currentUser()" doesn't evaluate to a function, so it can't be invoked.
How can i rewrite the code? thanks
The _auth.currentUser is not a function (it used to be, but changed about a year ago), but rather a property. It also isn't asynchronous, so you don't need await nor to return a Future.
So:
UserModel getUser() {
User user = _auth.currentUser;
return _userFromUser(user);
}
In this code, your argument is capitalised ('User') but in the code block you write 'user'.
UserModel _userFromUser(User) {
return user != null ? UserModel(uid: user.uid) : null;
}
Furthermore, for _auth.currentUser(), you do not need to use await as it does not return a future.

Getting Boolean State from Cloud_Firestore in dart

I'm making an app that needs to display two separate home pages depending on whether or not a counselor value equals true on my Cloud Firestore Database. I am new to Object Oriented Programing, dart, and Firestore so please bear with me.
What I'm trying to do is initialize a variable called counselor and set that equal to the Counselor field value on my database. Then I wish to first check if the user has signed in and if they have signed it that's when I use a series of if statements to see whether or or not the counselor boolean equals true or false. and depending on the result it will display a certain homepage.
I get an error message on my app saying that the I'm returning a null value on my counselor widget. I suspect this is because I'm setting the counselor variable to equal the name of the field Counselor on my database and not it's actual boolean value. Problem is I'm not aware of the syntax to circumvent this problem.
Here is my code
import 'package:strength_together/models/user.dart';
import 'package:strength_together/Screens/authenticate/authenticate.dart';
import 'package:strength_together/Screens/home/home.dart';
import 'package:strength_together/Screens/home/wrapper.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:strength_together/services/database.dart';
import 'package:strength_together/Screens/home/counsHome.dart';
class Wrapper extends StatelessWidget {
#override
Widget build(BuildContext context) {
final user = Provider.of<SUser>(context);
bool counselor = getCounselor();
//return either authenticate or home/couselor home
if (user == null){
return Authenticate();
}else if(counselor == true){
return CounselorHome();
}else if(counselor == false){
return Home();
}
}
}
// Database class
import 'package:cloud_firestore/cloud_firestore.dart';
class DatabaseService {
final String uid;
DatabaseService({this.uid});
//collection reference
final CollectionReference userCollection = FirebaseFirestore.instance
.collection('User Data');
Future updateUserData(String name, bool counselor) async {
return await userCollection.doc(uid).set({
'name': name,
'Counselor': true,
});
}
//get user data stream
Stream<QuerySnapshot> get userData {
return userCollection.snapshots();
}
Future<DocumentSnapshot> getDataSnapshotForCounselor() async
{
return await FirebaseFirestore.instance.collection('User Data')
.doc(uid)
.get();
}
bool getCounselorValue(DocumentSnapshot dataSnapshotForCounselor) {
//modify this by passing proper keyValue to get counselor.
return dataSnapshotForCounselor.data()['Counselor'];
}
}
// auth class
import 'package:firebase_auth/firebase_auth.dart';
import 'package:strength_together/Screens/authenticate/register.dart';
import 'package:strength_together/models/user.dart';
import 'package:strength_together/services/database.dart';
import 'package:flutter/material.dart';
class AuthService{
final FirebaseAuth _auth = FirebaseAuth.instance;
//instance of counselor
bool _counselor;
bool get counselor => counselor;
void setCounselor(bool counselor) {
_counselor = counselor;
}
//create user obj based on firebase user from my code
SUser _userFromFirebaseUser(User user){
return user != null ? SUser(uid: user.uid) : null;
}
//auth change user stream
Stream<SUser> get user {
return _auth.authStateChanges()
.map(_userFromFirebaseUser);
}
//method to sign in anon
Future signInAnon() async{
try{
UserCredential result = await _auth.signInAnonymously();
User user = result.user;
return _userFromFirebaseUser(user);
}catch(e){
print(e.toString());
return null;
}
}
//method to sign in with email/pass
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;
}
}
//method to register with email/pass
Future registerWithEmailAndPassword(String email, String password) async{
try{
UserCredential result = await _auth.createUserWithEmailAndPassword(email: email, password: password);
User user = result.user;
//create a new document for that user with the uid
await DatabaseService(uid: user.uid).updateUserData('New user', _counselor);
return _userFromFirebaseUser(user);
}catch(e){
print(e.toString());
return null;
}
}
//sign in with google
//sign out
Future signOut() async{
try{
return await _auth.signOut();
}catch(e){
print(e.toString());
return null;
}
}
There are lots of problems with your code . First of all you are using Firestore.instance and .document which are deprecated . Use FirebaseFirestore.instance and FirebaseFirestore.instance.collection(...).doc(...) instead.
Coming to your code , Use a FutureBuilder to decide which page to show , while deciding , you can show a CircularProgressIndicator to the user.
Next , this code
Firestore.instance.collection('User Data').document('Counselor');
returns a DocumentReference and not the actual value that is required .
So after you get the DocumentReference use .get() which returns a Future<DocumentSnapshot> , DocumentSnapshot class has a method data() which returns Map<String,dynamic>. Once you get the Map<> , you can simply get the data you want by passing the key value.
The whole process would look similar to this :
Future<bool> getCounselorValue() async {
return await FirebaseFirestore.instance.collection(...).doc(...).get().data()['keyvalue'];
}
Aagain , remember you are dealing with a Future so you have to use either await , .then() or FutureBuilder . I recommend FutureBuilder for your case , if you are not sure how to use it, refer to this . I also answered this which might be helpful if you want to dynamically decide which page to show to user first (refer to first method).
Edit:
Ok , so there was a little mistake in my code .Now I am sharing with you a little more code which you might find helpful .
make your class Stateful from Stateless and follow this code :
class Wrapper extends StatefulWidget{
WrapperState createState()=> WrapperState();
}
class WrapperState extends State<Wrapper>
{
Future<DocumentSnapshot> documentSnapshot;
User getUser(BuildContext context)
{
return Provider.of<User>(context);
}
dynamic getStartingPage(bool counselor,User user)
{
if (user == null){
return Authenticate();
}else if(counselor == true){
return CounselorHome();
}else if(counselor == false){
return Home();
}
}
Future<DocumentSnapshot> getDocumentSnapshotForCounselor() async
{
return await FirebaseFirestore.instance.collection(...).doc(...).get();
}
bool getCounselorValue(DocumentSnapshot documentSnapshotForCounselor)
{
//modify this by passing proper keyValue to get counselor.
return documentSnapshotForCounselor.data()['keyValue'];
}
#override
void initState()
{
super.initState();
documentSnapshot=getDocumentSnapshotForCounselor();
}
#override
Widget build(BuildContext context) {
return FutureBuilder(
future:documentSnapshot,
builder: (BuildContext ctx, AsyncSnapshot<dynamic> snapshot) {
if (snapshot.connectionState != ConnectionState.done) {
return Center( child : const CircularProgressIndicator());
}
else
return getStartingPage(getCounselorValue(snapshot.data),getUser(context));
}
);
}
}
Modify getDocumentSnapshotForCounselor and getCounselorValue methods ,so that you can get the value of the field from the database.
Upgrade to latest version of cloud_firestore , visit this to understand how to do it and what to import .
Edit 2:
When you sign in user ,either by email password or using google sign in etc. It returns a Future<UserCredential> , UserCredential has a property user , which returns User. Now what we want is, a unique uid of the user which we can get using User.uid :
UserCredential userCredential =await _auth.createUserWithEmailAndPassWord();
String uid= userCredential.user.uid;
Now create an entry for the user in the database using this uid:
FirebaseFirestore.instance.collection("User Data").doc(uid).set({"Counselor":true,"name":name});
Afterwards , to get the counselor value , :
FirebaseFirestore.instance.collection("User Data").doc(uid).get();
and
documentSnapshotForCounselor.data()['Counselor'];
The above code is just for an explanation , make appropriate changes to your code.

SignInAnonymously() doesn't return full user information, it returns "FirebaseUser(Instance of 'PlatformUser')"

Instead of returning full user info like UserId and stuff, I receive FirebaseUser(Instance of 'PlatformUser'). What seems to go wrong?
import 'package:firebase_auth/firebase_auth.dart';
class AuthService {
final FirebaseAuth _auth = FirebaseAuth.instance;
// sign in anon
Future signInAnon() async {
try {
AuthResult result = await _auth.signInAnonymously();
FirebaseUser user = result.user;
return user;
} catch (e) {
print(e.toString());
return null;
}
}
// sign in with email & password
// register with email & password
// sign out
}

Flutter FirebaseUser how to access the user data

I am learning Firebase with Flutter.
Currently making an anonymous login option, here is the class I created:
class AuthService {
final FirebaseAuth _auth = FirebaseAuth.instance;
// sign in anonymously
Future signInAnonymous() async {
try{
// signs in as anon user
AuthResult signInResult = await _auth.signInAnonymously();
// retruns currently signed in user, else null
FirebaseUser userFromResult = signInResult.user;
return userFromResult; // HERE: if I add .uid, the id object is displayed
}catch(e){
print(e.toString());
return null;
}
}
}
In my login page after creating an instance and using the method, when I print the result I get FirebaseUser(Instance of 'PlatformUser') insted of the user information, here is the code:
onPressed: () async {
dynamic result = await _auth.signInAnonymous();
if(result == null){print('Error signing in.');}
else{
print('Signed in successfully');
print(result);
}
How can I access the user data?
UPDATE: If I change return userFromResult; to return userFromResult.uid; the id string is returned.
I still wonder, however, how to print the full object.
Your Result inside of the onpressed is a dynamic type cast, but it is a FirebaseUser inside.
// onPressed Callback
dynamic result = await _auth.signInAnonymous();
You can change your SignIn method with the right return type and use instead of dynamic the FirebaseUser.
Future<FirebaseUser> signInAnonymous() async {
// [...]
return userFromResult; // HERE: if I add .uid, the id object is displayed
}
onPressed: () async {
FirebaseUser result = await _auth.signInAnonymous();
print(result.uid); // should contain the id
// [...]
The difference is that in version 0.13.x the user data is available, but in the version used in this example the bersion used is 0.16.x.

Resources