Flutter Firestore, Check if collection exists? [duplicate] - android

This question already has answers here:
In Dart/Flutter, how can I find out if there is no Collection in the Firestore database?
(4 answers)
Closed 1 year ago.
im very new to dart/firebase and im currently experimenting with it. Im trying to figure out if theres a way to find out if a collection exists or not.
Ive created a method where everytime a user registers, it creates a collection named after their userid. And everytime they sign in "I want to check if it exists", if not create it.
I dont want a user who signs in the 'dashboard' page without having a collection.
My current coding, creates a collection when they register, and also when the sign in lol, cant figure out to check if collection exists.
auth.dart
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import 'database.dart';
class Authentication {
static Future<User?> signInUsingEmailPassword({
required String email,
required String password,
required BuildContext context,
}) async {
FirebaseAuth auth = FirebaseAuth.instance;
User? user;
try {
UserCredential userCredential = await auth.signInWithEmailAndPassword(
email: email,
password: password,
);
user = userCredential.user;
// Create User Database file
await Database.createUserDataFile(
uid: user!.uid,
surname: 'surname',
mobile: 12345,
);
// Creates User Database
} 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.');
}
}
return user;
}
static Future<User?> registerUsingEmailPassword({
required String name,
required String email,
required String password,
required BuildContext context,
}) async {
FirebaseAuth auth = FirebaseAuth.instance;
User? user;
try {
UserCredential userCredential = await auth.createUserWithEmailAndPassword(
email: email,
password: password,
);
user = userCredential.user;
// Create User Database file
await Database.createUserDataFile(
uid: user!.uid,
surname: 'surname',
mobile: 12345,
);
// Creates User Database
await user.updateDisplayName(name);
await user.reload();
user = auth.currentUser;
} 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);
}
return user;
}
static Future<User?> refreshUser(User user) async {
FirebaseAuth auth = FirebaseAuth.instance;
await user.reload();
User? refreshedUser = auth.currentUser;
return refreshedUser;
}
}
database.dart
import 'package:cloud_firestore/cloud_firestore.dart';
final FirebaseFirestore _firestore = FirebaseFirestore.instance;
// Database Collection Name
final CollectionReference _mainCollection = _firestore.collection('_TestFB');
class Database {
static String? userUid;
// Create User Data File
static Future<void> createUserDataFile({
required String uid,
required String surname,
required int mobile,
}) async {
// - Col:_TestFB/Doc:UserData/Col:profile/
DocumentReference documentReferencer =
_mainCollection.doc('UserData').collection(uid).doc('Profile');
Map<String, dynamic> data = <String, dynamic>{
"surname": surname,
"mobile": mobile,
};
// Check if user Exists
//print('users exists?');
//
await documentReferencer
.set(data)
.whenComplete(() => print("UserData Profile Created for -- " + uid))
.catchError((e) => print(e));
}
}

If a collection doesn't exist, that technically means there are no documents in it. You can query for that collection and if it has 0 documents in it then that could mean it's absent.
FirebaseFirestore.instance
.collection('colName')
.limit(1)
.get()
.then((checkSnapshot) {
if (checkSnapshot.size == 0) {
print("Collection Absent");
}
});
The .limit(1)will fetch only one document from that collection if exists so that's important or you'll end up reading all the documents from it.

Related

Flutter Firebase Authentication requires 2 clicks for sign in

I just connected my app with firebase authentication but when i'm trying to click login button : it says
W/System ( 6835): Ignoring header X-Firebase-Locale because its value was null.
And here is my code about firebase authentication :
`
void signIn() async{
final User? user = (await auth.signInWithEmailAndPassword(email: mailController.text, password: passController.text)).user;
final uid = user!.uid;
if(uid != null){
if(this.mounted){
setState((){
success = 2;
userMail = user.email!;
userName = userMail;
userName = userMail.replaceFirst(userName[0],"");
userName = userName.substring(0,userName.indexOf("#"));
userName = userName.replaceFirst(userName[0],userName[0].toUpperCase());
});
}}
else{
setState((){
success = 3;
});
}
}
`
if(success == 2){
if(userMail.startsWith("1")){
Navigator.pushReplacement(context,MaterialPageRoute(builder:(context) => OgrenciPage(mail:userName)));
}
``
I've tried to creating sha-1 key, closing bluetooth connection but it never works.
I also face this problem earlier then solve this by making the function Future asyn{} and by using try catch block.
In my case i created the login class model where I perform all All login/signup functionalities
Here is the example code where you can see how to manage this:
class Login {
FirebaseAuth firebaseAuth = FirebaseAuth.instance;
Future<void> signInUser(
String email, String password, BuildContext context) async {
try {
await firebaseAuth.signInWithEmailAndPassword(
email: email, password: password);
} on FirebaseAuthException catch (e) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(
e.toString(),
),
backgroundColor: Colors.redAccent,
duration: const Duration(seconds: 2),
),
);
} catch (error) {
rethrow;
}
}
}

Flutter Firebase auth facebook not working

I'm trying to implement different login options for my flutter app users, but can't make the facebook one work(google and email are ok).
I've followed the installation guide from the package flutter_facebook_auth but still getting an error when the token provided from facebook is going to be used as a credential to create the firebase user:
my code:
import 'package:flutter_facebook_auth/flutter_facebook_auth.dart';
import 'package:firebase_auth/firebase_auth.dart';
final FirebaseAuth _auth = FirebaseAuth.instance;
String usermail = "";
Future returnToken(User user) async {
token = word + await user.getIdToken();
}
Future<List<String>> facebookSignin() async {
try {
final _instance = FacebookAuth.instance;
final result = await _instance.login(permissions: ["email"]);
if (result.status == LoginStatus.success) {
final OAuthCredential credential = FacebookAuthProvider.credential(result.accessToken.token);
final a = await _auth.signInWithCredential(credential); //the error is in this line
await _instance.getUserData().then((userData) async {
await _auth.currentUser.updateEmail(userData["email"]);
userMail = userData["email"];
});
await returnToken(a.user);
return ["ok"];
} else if (result.status == LoginStatus.cancelled) {
return ["Erro!", "Login cancelado"];
} else
return ["Erro!", "Falha no login"];
} catch (e) {
return ["Erro!", e.toString()];
}
}
The problem was on the secret key option:
I didn't add it on my app, so having this setting turned on blocked the app from generating a valid token to firebase.

createUserWithEmailAndPassword. The named parameter 'email' isn't defined

[createUserEmailAndPasswordError]
Error Screenshot:
I am trying to Auth login using firebase and this error comes up. I tried suing this. or type String before it as it was given in quick fix option but didn't work.
Full error message - The named parameter 'email' isn't defined.
Try correcting the name to an existing named parameter's name, or defining a named parameter with the name 'email'. dart(undefined_named_parameter)
Full code -
import 'package:firebase_auth/firebase_auth.dart';
import 'package:socialMediaApp/models/user.dart';
class AuthService {
final FirebaseAuth _auth = FirebaseAuth.instance;
//create user obj based on FirebaseUser
Users _userFromFirebaseUser(User user) {
return user != null ? Users(uid: user.uid) : null;
}
// sign in with email & password
// register with email & password
Future registerWithEmailAndPassword(String email, String password) async {
try {
UserCredential userCredential = (await _auth
.createUserWithEmailAndPassword(email: email, password: password));
User user = userCredential.user;
return _userFromFirebaseUser(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;
}
}
}

How to check If user is new or existing when login with google using firebase in flutter?

I am working on a project in which user data will be saved in Fire store in this i am making new document for user when the user sign In with google. here is my code below
import 'package:firebase_auth/firebase_auth.dart';
import 'package:gfd_official/User/User.dart';
import 'package:gfd_official/services/database.dart';
import 'package:google_sign_in/google_sign_in.dart';
class GSignInhelp {
final FirebaseAuth _auth = FirebaseAuth.instance;
//Firebase User
Userdat _userFromFirebase(User user) {
return user != null ? Userdat(uid: user.uid) : null;
}
//auth change user stream
Stream<Userdat> get user {
return _auth.authStateChanges().map(_userFromFirebase);
}
Future signInWithGoogle() async {
GoogleSignIn googleSignIn = GoogleSignIn();
final account = await googleSignIn.signIn();
final auth = await account.authentication;
final credential = GoogleAuthProvider.credential(
accessToken: auth.accessToken,
idToken: auth.idToken,
);
try {
final res = await _auth.signInWithCredential(credential);
User user = res.user;
await DatabaseService(uid: user.uid)
.updateUserRole(user.displayName, user.email, 'basic');
return _userFromFirebase(user);
} catch (e) {
print(e.toString());
return null;
}
}
Future logOut() async {
try {
GoogleSignIn().signOut();
return await _auth.signOut();
} catch (e) {
print(e.toString());
return null;
}
}
}
I am successfully able to change user role in fire store but as you can see when user signs in the database values will be set to default but I don't want this. So, my question is how can I check that if user is signed in for first time or returning user.
If user is returning then I don't want to reset user data in Fire store and If user is new then create document in Fire store with default values.
Conclusion, How can I check that When user signs in with google that is user a existing user or new a user?
You can check the user whether he is a new or previously registered user via User Credential and through you can retrieve the authResult.additionalUserInfo.isNewUser if the user is not already registered before.
You can use this code:
Future<UserCredential> signInWithGoogle(BuildContext context) async {
FirebaseAuth _auth = FirebaseAuth.instance;
// Trigger the authentication flow
final GoogleSignInAccount googleUser = await GoogleSignIn().signIn();
// Obtain the auth details from the request
final GoogleSignInAuthentication googleAuth =
await googleUser.authentication;
// Create a new credential
final GoogleAuthCredential credential = GoogleAuthProvider.credential(
accessToken: googleAuth.accessToken,
idToken: googleAuth.idToken,
);
final UserCredential authResult =
await _auth.signInWithCredential(credential);
final User user = authResult.user;
///Her to check isNewUser OR Not
if (authResult.additionalUserInfo.isNewUser) {
if (user != null) {
//You can her set data user in Fire store
//Ex: Go to RegisterPage()
}
}
} else {
//Ex: Go to HomePage()
}
return await FirebaseAuth.instance.signInWithCredential(credential);
}
Here is the full code for Google sign in and sign out :-
class GSignInhelp {
final FirebaseAuth _auth = FirebaseAuth.instance; //Firebase User
Userdat _userFromFirebaseUser(User user) {
return user != null ? Userdat(uid: user.uid) : null; } //auth
change user stream
Stream get user {
return _auth.authStateChanges().map(_userFromFirebaseUser);
}
Future signInWithGoogle() async {
GoogleSignIn googleSignIn =
GoogleSignIn();

'Sign Up' Error: The setter 'displayName=' was called on null." gets displayed on console. Sign Up button doesn't route to next page

The app runs however when clicking the SignUp Button I am not able to go on to the next routed paged. The account does get created as seen from console.firebase, and the only way to go to the next page is to Sign In again with the created credentials.
import 'package:firebase_auth/firebase_auth.dart';
import 'package:firebase_core/firebase_core.dart';
class AuthService {
final FirebaseAuth _firebaseAuth = FirebaseAuth.instance;
Stream<String> get authStateChanges => _firebaseAuth.authStateChanges().map(
(User user) => user?.uid,
);
// // GET UID
// Future<String> getCurrentUID() async {
// return (await _firebaseAuth.currentUser()).uid;
// }
// Email & Password Sign Up
Future<String> createUserWithEmailAndPassword(
String email, String password, String name) async {
final authResult = await _firebaseAuth.createUserWithEmailAndPassword(
email: email,
password: password,
);
// Update the username
await updateUserName(name, authResult.user);
return authResult.user.uid;
}
Future updateUserName(String name, User currentUser) async {
var userUpdateInfo = updateProfile();
userUpdateInfo.displayName = name;
await currentUser.updateProfile(displayName: userUpdateInfo);
await currentUser.reload();
}
// Email & Password Sign In
Future<String> signInWithEmailAndPassword(
String email, String password) async {
return (await _firebaseAuth.signInWithEmailAndPassword(
email: email, password: password))
.user
.uid;
}
// Sign Out
signOut() {
return _firebaseAuth.signOut();
}
}
updateProfile() {
}
In updateUserName method, the below codes are executed, so try to comment or delete it.
// Sign Out
signOut() {
return _firebaseAuth.signOut();
}

Categories

Resources