Is it possible to use a variable within a variable name? - flutter

I have a class for Player that has nextDate, loginDate and saveDate.
Below code works fine and able to retrieve the fields.
DocumentSnapshot documentSnapshot =
await db.collection(Paths.playersPath).doc(uid).get();
Player player = Player.fromFirestore(documentSnapshot);
print('print ${player.nextDate}');
print('print ${player.loginDate}');
print('print ${player.saveDate}');
My question now is if it is possible to use a variable for the nextDate, loginDate and saveDate so that I can just pass which date should I retrieve.
I tried the following but it is not working.
String dateName = 'nextDate';
DocumentSnapshot documentSnapshot =
await db.collection(Paths.playersPath).doc(uid).get();
Player player = Player.fromFirestore(documentSnapshot);
print('print ${player.$dateName}');
Please help. Thanks!

As far as the code snippet is concerned, I can see you have already defined a method fromFirebase to serialize it, in that case you must extract the data payload from the DocumentSnapshot provided by the Firebase DB by using the data method provided by the DocumentSnapshot class. The problem in your case is you're trying to serialize the DocumentSnapshot itself which is not a class of type Map<String, dynamic> which is need for json serialization. If you take a look at the docs, the data method provides a Map<String, dynamic>
Another alternative could be
If you are using FlutterFire plugins that are officially developed by the Firebase and Flutter teams, you can use the withConverter method which can serialize the response for you to the Player class in your case. Here you can find more info about the same.

unluckily, in Flutter mirrors are not available.
You can look it up in the official documentation about this matter.
Nonetheless, the most straightforward workaround is using a Map, so that the keys in that map are your options, and the values the actual property you want to use.
There's a good example in this previous answer.

Related

Convert firebase stream to an mongodb stream in flutter

In my flutter project i have streams from firebase like this:
final CollectionReference _peopleRef=FirebaseFirestore.instance.collection('people');
List<People> _peopleListFromSnapshot(QuerySnapshot snapshot){
return snapshot.docs.map((doc) {
return People.fromJson(doc);
}).toList();
}
Stream<List<People>> getListAllPeopleStream(){
return _peopleRef.snapshots().map(_peopleListFromSnapshot);
}
Now i would like to receive the data from mongodb and after searching the documentation i guess i have to work with cursors and watch(), but the documentation doesn`t have code examples for flutter/dart.
Also i can`t find a tutorial via google, so i would highly appreciate any kind of help how to convert this stream to an mongodb change stream.
Let me know if you need more information!
Thanks!

How to pass List and other data from one screen to another in flutter?

I made an API call and returned a list data and few other values. I made the API call in one screen in the initState now and I need the list and other data in other 2 screens without Navigation. Is this possible. I am also using provider package. I am new to flutter so any help would be highly appreciated. Thank You.
List<YourClassName> list = [];
class ExampleProvider with ChangeNotifier {
getList(){
list = await yourApiCall();
notifyListeners();
}
}
Your provider class should look like this. When your api returns, you need to use that equation. With that way you can call it everywhere your list with
Provider.of<ExampleProvider>(context).list;

Flutter Hive save custom object with list of custom objects gone after restarting app

I am using the Hive- Package in my project to store some data locally. That has been working fine so far, but now I am facing an issue:
I have a Custom-Class which also has a field with another Custom-Class:
part 'hive_vitals_interface.g.dart';
#HiveType(typeId: 1)
class HiveVitals extends HiveObject {
#HiveField(0)
String? id;
#HiveField(1)
DateTime? date;
#HiveField(2)
List<HiveDiscomfort> otherDiscomfort;
#HiveField(3)
List<HiveDiscomfort> mentalDiscomfort;
HiveVitals({
this.id,
this.date,
this.otherDiscomfort = const [],
this.mentalDiscomfort = const [],
});
}
And my HiveDiscomforts-Class:
part 'hive_discomfort_interface.g.dart';
#HiveType(typeId: 2)
class HiveDiscomfort extends HiveObject {
#HiveField(0)
String? title;
#HiveField(1)
int? intensity;
HiveDiscomfort({
this.title,
this.intensity,
});
}
I am trying to save HiveVitals like this:
static Future<void> addVitals(HiveVitals hiveVitals) async {
final vitalsBox = getVitalsBox();
await vitalsBox.put(hiveVitals.date!.toIso8601String(), hiveVitals);
}
And retrieve it like this:
static List<HiveVitals> getVitals() {
Box<HiveVitals> box = getVitalsBox();
List<HiveVitals> hiveVitals = box.values.toList();
return hiveVitals;
}
Problem:
I don't get any errors. In fact when saving my object and checking it in the debugger, everything is saved correctly. However when restarting the app, my List<HiveDiscomfort> fields are always empty again! But the rest of the HiveVitals-Fields are still saved correctly!?
What am I missing here? I don't get it... Any help is appreciated! Let me know if you need anything else!
Also opened an issue on Github.
I use this method and it works for me as List doesn't require registering an adapter:
await Hive.openBox<List>(bookmarks);
Add data like this:
boxValue.put(index, [
question.title,
question.options,
],
);
And you can access the data via ValueListenableBuilder.
If you're saying data is being saved and everything worked fine till you didn't restart the app. So the problem may be :
After restarting your app, you had may put a function that cleared all the data saved in Hive as soon as app starts.
Check this one.If like this will there then remove that line or function that clear all the data from hive DB.
Updated answer:
My previous solution got me thinking and I think I know why nested lists are not persisted.
It seems like hive is not checking for list equality and therefore never persist the changes, but uses the object as it is currently in memory. So, that is why as long as the application runs the object is correctly in memory, but when the app is closed hive does not persist the data as it thinks that the data (here the lists) never changed, even though they changed (this is my guess now without looking further into the code of the hive package).
So that means the solution would be to check for equality of the lists in the equals method. For this example it would be:
#override
bool operator ==(Object other) =>
identical(this, other) ||
other is HiveVitals &&
runtimeType == other.runtimeType &&
id == other.id &&
date == other.date &&
listEquals(otherDiscomfort, other.otherDiscomfort) &&
listEquals(mentalDiscomfort, other.mentalDiscomfort);
For me this solution works.
Old answer:
I had the same issue...
I try to explain my solution based on this example.
Given an object HiveVitals hiveVitals = HiveVitals(), whenever I tried to add something to the nested list of my custom object like hiveVitals.otherDiscomfort.add(), it was saved but not persisted (it was gone whenever I restarted the app). What I did was the following when I wanted to add something to the nested list:
List<HiveDiscomfort> tempList = [...hiveVitals.otherDiscomfort];
tempList.add(newData);
hiveVitals.otherDiscomfort = tempList;
That worked for me, now my data is persisted.
I think this is a problem with the package because I have the same issue that everything works okay but with restarting the app the data disappears. So I asked the question at hive flutter github and no answers yet. So I ask u to open an issue at hive flutter github to let them know that this is a real problem we face it.
Here are a couple of hints about the issue which may be why the data is lost:
Hive FAQ: What happens if my app is killed? The worst thing that can happen is
that you lose the last entry if it isn't written completely yet. Hive
has built-in integrity checking and crash recovery and takes care of
everything.
Limitations: Keys have to be 32 bit unsigned integers or ASCII Strings with a max
length of 255 chars. The supported integer values include all
integers between -2^53 and 2^53, and some integers with larger
magnitude Objects are not allowed to contain cycles. Hive will not
detect them and storing will result in an infinite loop. Only one
process can access a box at any time. Bad things happen otherwise.
Boxes are stored as files in the user's app-directory. Common illegal
characters/symbols such as /%& should therefore be avoided.
The most likely cause though may be related to improper implementation of the Hive Relationships behavior. Are you using HiveLists? If not look into this more closely. Secondly, you may just be trying to save too much when the app is killed. Try changing the save operation before the app is killed to verify proper behavior.

How can you store lists of Items in Flutter

How could you store something like that even when the app is closed in Flutter:
Class myList {
String id;
List<Item> list;
}
Class Item{
//Many property’s
}
I thought maybe I could do that with "sqflite", a flutter dependency, but I have no Idea how I could store there this List<Item>. Do you have any idea?
Btw: I need multiple of these "myList" instances.
You can store it using sqflite,hive or shared preferences.Try to save it under flutter shared preferences. These are two methods that you can use.
Using shared preferences
1)First create a shared preference instance
SharedPreferences prefs = await SharedPreferences.getInstance();
Then save the relevant data type.here you need to put a object list so add the list and convert it to the String using jsonEncode.
Map<String,List<Item>> map={mylist.id: mylist.list};
prefs.setString("itemList", json.encode(map));
Then you can retrieve data like this
Map<String,List<Item>> map=json.decode(prefs.getString("itemList")).asMap();
2)Using Hive
First Create the hive databse.you can put any name here
var box = Hive.box('myBox');
Then add the object in to that database
var myList = myList()
..id = your id here
..list = add list here;
var name = box.add(myList);
You can get anywhere this data list.
print(box.getAt(0));
You can try hive package. It is a lightweight local storage passage and it is a good idea to use hive because it has better benchmarks for reading and writes. You can search for the tutorial for the hive. or just read the documentation.

save data when app closed in flutter provider

https://pub.dev/packages/provider
I used this package for the cart and it works.
But when the app closes, the cart model becomes empty.
What can I do for this problem?
I want to save the previous data when the app is opened.
thanks
you can also use the offline database
for example SQFLITE
Using something like Shared_Prefs sould solve it
it will store your data locally and retrieve them in your providers
create instance
SharedPreferences prefs = await SharedPreferences.getInstance();
set your data
await prefs.setInt('counter', 1);
in your provider retrieve if exist like this
if(prefs.getInt('counter') != null){
someVar = prefs.getInt('counter');
}
you can remove like
prefs.remove('counter');
Note: you can save/retrieve with one of the following types
Only primitive types can be used: int, double, bool, string, and stringList.