Always update widget flutter - android

I want a widget or something where my int automatically updates with my realtime database. Does anyone knows how i can do this. The code that i want to update the whole time is:
userid = _userId.replaceAll('#', "").replaceAll("[", "").replaceAll("]", "");
DatabaseReference ref = FirebaseDatabase.instance.ref("credits");
final snapshot = await ref.child('$userid').get();
if (snapshot.exists) {
moneyd = snapshot.value.toString();
print(snapshot.value);
} else {
print('No data available.');
}
print('hello $moneyd');
if (int.tryParse(moneyd) != null) {
money = int.tryParse(moneyd) ?? 0;
} else {
print('Invalid value for moneyd: $moneyd');
}
The money value is now hard coded: money = 10; but i want it to be int money = int.parse(monyd);. I want this because, the string is 10 everytime that i restart the app but i want it to be the last saved string in firebase.
String moneyd = '';

In this case, he will need to use a StreamBuilder. FirebaseDatabase lets you listen for events:
StreamBuilder<Event>(
stream: ref.child('credits')child('$userid').onValue,
builder: (context, snapshot) {
if (snapshot.hasData) {
// Get a list of messages from snapshot data
List<dynamic> data = snapshot.data.snapshot.value;
moneyd = snapshot.value.toString();
print(snapshot.value);
// Return a ListView widget to display messages
return Text(moneyd);
} else if (snapshot.hasError) {
return Text('Something went wrong');
} else {
return Text('Loading...');
}
},
),

Related

GetStorage always returns null in flutter

Code
print("Before : ${GetStorage().read("XXX")}");
GetStorage().write("XXX", 1);
print("After : ${GetStorage().read("XXX")}");
This is my Code. Every time I run the App, the Output is
Before : null
After : 1
Why is the storage data getting cleared everytime I restart the App? I thought this was an alternative to SharedPreference which works just fine. Have I missed something?
Before anything, initialize the package, normally I do this on main.dart
main() async {
await GetStorage.init();
}
Create an instance from GetStorage, I always put a name on the box, if not it will put "GetStorage" by default. It needs to have a name so it can retrieve your data.
GetStorage getStorage = GetStorage('myData');
After that you can write and retrieve data from it, I recommend you to "await" all reads and writes.
await getStorage.write('XXX', 1);
var a = await getStorage.read('XXX');
print(a); /// 1
I recommend you to put a name on the box according to what you are storing.
You should await for GetStorage.init().
void main() async {
await GetStorage.init();
print("Before : ${GetStorage().read("XXX")}");
GetStorage().write("XXX", 1);
print("After : ${GetStorage().read("XXX")}");
}
final _userBox = () => GetStorage('User');
class UserPref {
void call(){
_userBox.call()..initStorage;
}
dynamic setValueInt(String key, int value) {
return 0.val(key, getBox: _userBox).val = value;
}
String setValue(String key, String value) {
return ''.val(key, getBox: _userBox).val = value;
}
dynamic getValueInt(String key) {
return (-1).val(key,getBox: _userBox).val;
}
dynamic getValue(String key) {
return ''.val(key,getBox: _userBox).val;
}
void setUser(User user) {
''.val('uname', getBox: _userBox).val = user.uname ?? '';
(-1).val('gender', getBox: _userBox).val = user.gender ?? -1;
''.val('born', getBox: _userBox).val = user.born.toString();
true.val('enabled', getBox: _userBox).val = user.enabled ?? true;
}
User getUser() {
final String? uname = ''.val('uname',getBox: _userBox).val;
final int? gender = (-1).val('gender',getBox: _userBox).val;
final DateTime? born = ''.val('born',getBox: _userBox).val == '' ? null : DateTime.parse(''.val('born',getBox: _userBox).val);
final bool? enabled = true.val('enabled',getBox: _userBox).val;
return User(
uname: uname,
gender: gender,
born: born,
enabled: enabled,
);
}
}
///INIT:
#override
void initState() {
//The init function must be written separately from the read/write function due to being asynchronous.
UserPref().call();
}
//OR
Future<void> main() async {
//await GetStorage.init();
UserPref().call();
}
///USAGE:
class MyStatefulWidget extends StatefulWidget {
final Users prefUser = UserPref().getUser();
...
}
//OR
#override
Widget build(BuildContext context) {
final Users prefUser = UserPref().getUser();
return ...;
}

How to retrieve a Map values inside a field of a specific document in firestore using flutter?

I want to get all the Values of the map which is under "Subjects" field. And I also want to listen if any updates or changes made to those values. I actually want to add al those values and store in a variable. Can someone please tell me how can i achieve this?
Here is the structure of the collection.
This is how im adding the subjects whenever a user enters the subject name
onPressed: () async {
temp = qrdataFeed.text;
int index = qrdataFeed.text.indexOf('-');
subject = qrdataFeed.text.substring(0, index);
print("Subject name is $subject");
numberOfClasses = await FirebaseFirestore.instance
.collection('tutors')
.doc(uid)
.get()
.then((doc) async {
Map<String, dynamic> map = await doc.data();
if (!map.containsKey('Subjects')) {
await tutor_details.doc(uid).set({
'Subjects': {'$subject': initialValue},
}, SetOptions(merge: true));
}
if (doc.data()['Subjects']['$subject'] !=
'$subject') {
if (!map.containsKey('$subject')) {
await tutor_details.doc(uid).set({
'Subjects': {'$subject': initialValue}
}, SetOptions(merge: true));
}
}
var val = await doc.data()['Subjects']['$subject'];
return val;
});
if (!mounted) return;
setState(() {
qrData = qrdataFeed.text;
scanned = true;
print('done');
//if (temp != qrdataFeed.text)
numberOfClasses += 1;
print('$numberOfClasses is printed');
});
await tutor_details.doc(uid).set({
'Subjects': {'$subject': numberOfClasses},
}, SetOptions(merge: true));
}
},
Posting the #NisanthReddy's solution as a Community Wiki for visibility.
A better architecture would be to have one class at the root to handle all your transactions and to also notify any listener in your code.
You should always call this class to update and you can add listeners to this class from any widget you want. This way you will have everything Firestore-related in one place.

Flutter String is in Future null

I want to use a string in this function that has the phone number of the device.
I get the phone number with this:
Future<void> initMobilNumberState() async {
if (!await MobileNumber.hasPhonePermission) {
await MobileNumber.requestPhonePermission;
return;
}
String mobileNumber = '';
try {
mobileNumber = await MobileNumber.mobileNumber;
_simCard = await MobileNumber.getSimCards;
} on PlatformException catch (e) {
debugPrint("Failed to get mobile number because of '${e.message}'");
}
if (!mounted) return;
setState(() {
var re = RegExp(r'\+[^]*');
_mobileNumber = mobileNumber.replaceRange(0, 3, ''.replaceAll(re, '+'));
});
}
My problem is that if I want to print _mobileNumber or use it in http.get I get null or a error with "Invalid Arguments"
Future<http.Response> _fetchSampleData() async {
String s = _mobileNumber;
print(s);
return http.get('http://test.php?TestPhone=' + _mobileNumber);
}
Future<void> getDataFromServer() async {
final response = await _fetchSampleData();
if (response.statusCode == 200) {
Map<String, dynamic> data = json.decode(response.body);
_list = data.values.toList();
} else {
// If the server did not return a 200 OK response,
// then throw an exception.
showAlertNoInternet(context);
print('Failed to load data from server');
}
}
Where is my mistake?
The problem is that I want to call the phone number before it has even been fetched. So this always resulted in null. I fixed this by fetching the number when I start the app with all the other data I need.

Flutter how to get a Future<bool> to a normal bool type

Hi I'm trying to get a Future to be used as a normal boolean, how do I use this function as the determiner for a normal boolean without it giving me an incorrect type error?
Future<bool> checkIfOnAnyChats() async {
FirebaseUser user = await _auth.currentUser();
final QuerySnapshot result = await _firestore
.collection('chats')
.where('members', arrayContains: _username)
.getDocuments();
final List<DocumentSnapshot> documents = result.documents;
if(documents.length > 0) {
return Future<bool>.value(true);
}else{
return Future<bool>.value(false);
}
}
How do I apply it to a normal type boolean and not get this error? Thanks.
you don't need to convert bool into future, as you are in async method it will return future only.
you can get that value in initstate, you can not get value outside any method.
bool _isInChat;
#override
void initState() {
super.initState();
CheckIfOnAnyChats().then((value){
SetState((){
_isInChat = value;
});
});
}

Extracting info from QuerySnapshot variable in flutter app

This code is running fine with futurebuilder and i m getting a listview properly.
But i want to see into the documents n print the details in console. I m not getting any idea about how to do this with QuerySnapshot variable.
Future getP() async {
var firestore = Firestore.instance;
var q = await firestore.collection('place_list').getDocuments();
print(q.documents);
return q.documents;
}
I think I have to call it n wait for the responses then print them, can anyone guide me how to do it?
List<Map<String, dynamic>> list =
q.documents.map((DocumentSnapshot doc){
return doc.data;
}).toList();
print(list);
Though the answer is right the current firebase API has changed drastically now to access QuerySnapshot one can follow the below code.
FirebaseFirestore.instance
.collection('users')
.get()
.then((QuerySnapshot querySnapshot) => {
querySnapshot.docs.forEach((doc) {
print(doc["first_name"]);
});
});
And if you are using async/await then first you need to resolve the AsyncSnapshot and then work on it. If you like:
return FutureBuilder(
future: PropertyService(uid:userId).getUserProperties(),
builder: (BuildContext context, AsyncSnapshot<QuerySnapshot> snapshot){
if (snapshot.hasError) {
return Text("Something went wrong");
}
if (snapshot.connectionState == ConnectionState.done) {
snapshot.data.docs.forEach((element) {
Property property = Property.fromJson(element.data());
});
return Text("Demo Text");
}
return LoadingPage();
}
);
taken from url
//But I am not getting all the documents present in my firestore DB collection. The first 10 or so entries are getting printed in the console. //
I think that is standard behavior. If you have one million records it can't print everything in console. To check any particular set of documents you have to filter through where condition in query.
If you have still this problem, I hope this will help you.
This is how I get data from QuerySnapshot:
QuerySnapshot snapshot =
await userCollection.where("uid", isEqualTo: uid).get();
List<Object?> data = snapshot.docs.map((e) {
return e.data();
}).toList();
Map<dynamic, dynamic> userData = data[0] as Map;
print(userData["email"]);
Or you can easily get data by:
QuerySnapshot querySnapshot =
await userCollection.where("uid", isEqualTo: uid).get();
print(querySnapshot.docs[0)['fieldName']);

Categories

Resources