Firebase Flutter Does Not Recognize My String as Parameter - firebase

I am trying to get user email,save to shared preferences and use as collection name in another file.
my code to save
Future<void> saveEmail() async {
var sharedPreferences = await SharedPreferences.getInstance();
sharedPreferences.setString("email", _emailKontroller.text);}
no problem here, I can save data to sharedPreferences and read data from another file.
my code to read
#override
void initState() {
// TODO: implement initState
void initilaizeEmail() async {
var sharedPreferences = await SharedPreferences.getInstance();
_email = sharedPreferences.getString("email");
print(_email);
}
initilaizeEmail();
setState(() {});
}
output
I/flutter ( 3274): a#a.com
where I use as parameter my sharedPreferences Data:
query: FirebaseFirestore.instance
.collection("test")
.doc("$_email")
.collection("class 0"),
// to fetch real-time data
isLive: false,
I can not see anything on screen but, if I delete
_email
and type "a#a.com" manually everything works.What is the problem?

The problem is that initilaizeEmail is an async method, and you're not waiting for its result. To fix this:
await initilaizeEmail();
I also recommend fixing the name of the method to be initializeEmail. While it won't change the behavior, spelling mistakes tend distract from other problems.

I solved my problem with using
Future Builder

Related

Shared Preferences not working when using FCM backgroundHandler

I am working on this Flutter app and I have implemented Firebase Cloud Messaging. I added the following code to make sure I can use the Shared Preferences package. It seems to work, but the functionality does not work correctly.
Extra configuration code
if (Platform.isAndroid) SharedPreferencesAndroid.registerWith();
if (Platform.isIOS) SharedPreferencesIOS.registerWith();
The backgroundhandler in action
Future<void> backgroundHandler(RemoteMessage message) async {
await Firebase.initializeApp();
if (Platform.isAndroid) SharedPreferencesAndroid.registerWith();
if (Platform.isIOS) SharedPreferencesIOS.registerWith();
print("App is in background: Message received ");
final prefs = await SharedPreferences.getInstance();
final listOfTopics = prefs.getStringList('out_of_stock_topics') ?? [];
String topic = 'default_topic';
if (listOfTopics.contains(topic)) {
listOfTopics.remove(topic);
await prefs.setStringList('out_of_stock_topics', listOfTopics);
}
}
The code above deletes the topic in the list. Then the list is set with prefs.setStringList. I checked, and the code goes into the if statement. It removes the item from the list. But something goes wrong in prefs.setStringList I suppose.
Because later I use the following code to check the items in the 'out_of_stock_topics' list.
Code to check list of topics
final prefs = await SharedPreferences.getInstance();
final listOfTopics =
prefs.getStringList('out_of_stock_topics') ?? [];
print(listOfTopics);
But the topic is not correctly deleted and is still there. I think there is something wrong in the backend of the backgroundhandler. I tested this feature with 2 buttons: "add topic" and "delete topic". And with those separate buttons it does delete the item from the 'out_of_stock_topics' list.
Does anyone know how to fix this problem?
Thanks!

Flutter Provider update user data in firestore

I'm trying to refactor my code to reduce Firebase read operations. For this I'm using Sharedpreferences. The code is structured in such a way that there's a provider that take's care of the update process and saves the new values in shared preferences. Here is the code.
submit() async {
final User user = _auth.currentUser;
DocumentReference ref =
FirebaseFirestore.instance.collection('users').doc(user.uid);
final prefs = await SharedPreferences.getInstance();
try {
if (_image != null){
mediaurl= await uploadImage();
await ref.update({"MediaURL": mediaurl});
prefs.setString("MediaURL", mediaurl);
}
if(username!=null){
ref.update({"username":userNamecontroller.text});
prefs.setString('username', username);
}
if(description!=null){
ref.update({"description":descriptionController.text});
prefs.setString('description', description);
}
} catch (e) {print("tHE ERROR IS $e");}
notifyListeners();
}
The problem however is the submit function does not work. No data is updated to firebase and the error from my catch block is
tHE ERROR IS NoSuchMethodError: The getter 'absolute' was called on null.
Any ideas what this 'absolute' is?

Download data before build - method

I want to build a contactScreen for my flutter app with an array downloaded from firebase. The array is correctly downloaded, but while building the app the array stays empty. With some tests (the print-statements) I figured out, that the app builds the screen and at the same time download the data (with getUserData()). So the download is not fast enough. (After a reload everything works fine).
#override
void initState() {
super.initState();
getUserData();
print(contacts);
}
getUserData() async {
var userData = await FirebaseFirestore.instance
.collection('users')
.doc(currentUser)
.get();
print(userData.data()!['contacts']);
contacts = userData.data()!['contacts'];
}
Is it possible to download the data before the build method every time? I can't use the straembuilder because it's already in use for another download.
create a variable bool isLoading = true
getUserData() {
//await retrieve data
//after data is retrieved
setState(() {
isLoading = false;
});
}
In your build method:
isLoading ? Container(child: Text('Loading...')) : YourScreen()

Google Firestore Database: Where are phantom document reads coming from? [duplicate]

there guys, I do have an interesting problem here and I would be really glad if any of you it will be able to help me with that.
What's my app flow:
Register with the email, password and some other details:
User firebase in order to auth the user and create an account via email and password, at the same time I'm writing the custom data of the user to the database.
Log in the user.
That's it, that's all my basic logic, and how you can see I'm not doing any reading from the DB so far as I know.
Now... the problem is that from some weird reason when I'm registering my user I'm going to the firebase console to see the usage of my DB and I will see something like... for one user which was created I will have 1 write (which is fine as I was expected) but also 13-20 READS FROM DB.
Now that's my question, WHY on earth I have reads on firestorm when I'm doing just auth and writes?
Here it's my DB code which I'm using right now.
class DatabaseFirebase implements BaseDataBase {
final FirebaseAuth _firebaseAuth = FirebaseAuth.instance;
final FirebaseStorage _storage = FirebaseStorage.instance;
FirebaseUser _firebaseUser;
Firestore _firestore = Firestore.instance;
#override
Future<String> login(String email, String password) async {
_firebaseUser = await _firebaseAuth.signInWithEmailAndPassword(
email: email, password: password);
return _firebaseUser.uid;
}
#override
Future<String> register(String email, String password) async {
_firebaseUser = await _firebaseAuth.createUserWithEmailAndPassword(
email: email, password: password);
return _firebaseUser.uid;
}
#override
Future<UserData> getCurrentUser() async {
if (_firebaseUser == null)
_firebaseUser = await _firebaseAuth.currentUser();
UserData user = UserData();
user.email = _firebaseUser?.email;
user.name = _firebaseUser?.displayName;
return user;
}
#override
Future<void> logout() async {
_firebaseAuth.signOut();
}
#override
Future<void> onAuthStateChanged(void Function(FirebaseUser) callback) async {
_firebaseAuth.onAuthStateChanged.listen(callback);
}
#override
Future<void> writeUser(UserData user) async {
_firestore.collection("Users").add(user.toMap()).catchError((error) {
print(error);
});
}
}
If some of you know could you explain to me where/how I need to search in order to find this bug? Because how you can see I'm not using any read what so ever.
It's impossible to know for sure given that we don't understand all possible routes of access into your database, but you should be aware that use of the Firebase console will incur reads. If you leave the console open on a collection/document with busy write activity, the console will automatically read the changes that update the console's display. This is very often the source of unexpected reads.
Without full reproduction steps of exactly all the steps you're taking, there's no way to know for sure.
Firebase currently does not provide tools to track the origin of document reads. If you need to measure specific reads from your app, you will have to track that yourself somehow.

Firestore - unexpected reads

there guys, I do have an interesting problem here and I would be really glad if any of you it will be able to help me with that.
What's my app flow:
Register with the email, password and some other details:
User firebase in order to auth the user and create an account via email and password, at the same time I'm writing the custom data of the user to the database.
Log in the user.
That's it, that's all my basic logic, and how you can see I'm not doing any reading from the DB so far as I know.
Now... the problem is that from some weird reason when I'm registering my user I'm going to the firebase console to see the usage of my DB and I will see something like... for one user which was created I will have 1 write (which is fine as I was expected) but also 13-20 READS FROM DB.
Now that's my question, WHY on earth I have reads on firestorm when I'm doing just auth and writes?
Here it's my DB code which I'm using right now.
class DatabaseFirebase implements BaseDataBase {
final FirebaseAuth _firebaseAuth = FirebaseAuth.instance;
final FirebaseStorage _storage = FirebaseStorage.instance;
FirebaseUser _firebaseUser;
Firestore _firestore = Firestore.instance;
#override
Future<String> login(String email, String password) async {
_firebaseUser = await _firebaseAuth.signInWithEmailAndPassword(
email: email, password: password);
return _firebaseUser.uid;
}
#override
Future<String> register(String email, String password) async {
_firebaseUser = await _firebaseAuth.createUserWithEmailAndPassword(
email: email, password: password);
return _firebaseUser.uid;
}
#override
Future<UserData> getCurrentUser() async {
if (_firebaseUser == null)
_firebaseUser = await _firebaseAuth.currentUser();
UserData user = UserData();
user.email = _firebaseUser?.email;
user.name = _firebaseUser?.displayName;
return user;
}
#override
Future<void> logout() async {
_firebaseAuth.signOut();
}
#override
Future<void> onAuthStateChanged(void Function(FirebaseUser) callback) async {
_firebaseAuth.onAuthStateChanged.listen(callback);
}
#override
Future<void> writeUser(UserData user) async {
_firestore.collection("Users").add(user.toMap()).catchError((error) {
print(error);
});
}
}
If some of you know could you explain to me where/how I need to search in order to find this bug? Because how you can see I'm not using any read what so ever.
It's impossible to know for sure given that we don't understand all possible routes of access into your database, but you should be aware that use of the Firebase console will incur reads. If you leave the console open on a collection/document with busy write activity, the console will automatically read the changes that update the console's display. This is very often the source of unexpected reads.
Without full reproduction steps of exactly all the steps you're taking, there's no way to know for sure.
Firebase currently does not provide tools to track the origin of document reads. If you need to measure specific reads from your app, you will have to track that yourself somehow.

Resources