i wanna get a Data from GetStorage(),
i got a Shop List and i can use it as Static for only page, that way im saving my List in GetStorage,if i go to another Page that will showed also. Like a SharedPreferences. How can i show a data from GetStorage List Value , like
Text(basket[name]), that will show only the Names,
Text(basket[price]), that will show only Prices,
var basketsd = GetStorage("totalList");
My ProductModel for Shop,
class PriceModel2 {
final String name;
final double price;
PriceModel2({
this.name,
this.price,
});
}
its also not worked.
Text(controller.basketsd.read(["name"])
Container(
height: Get.size.height * 0.3,
child: Obx(() => ListView.builder(
itemCount: controller.basket.length,
itemBuilder: (BuildContext context, int index) {
return Column(
children: [
SizedBox(
height: 20,
),
Container(
width: Get.size.width,
child: ElevatedButton(
onPressed: () {
controller.basket
.remove(controller.basket[index]);
},
child: (Text(controller.basketsd.read(["name"]) +
" " +
controller.basket[index].price.toString() +
" €"))),
),
SizedBox(
height: 20,
),
],
);
})),
),
Codes show like this ,
(https://prnt.sc/1fs6mbf)
There's a couple issues here. At least from what you're sharing, you're never really storing your PriceModel2 object properly. If you try and store a random custom object, GetStorage will not know what to do with it. (Neither would SharedPreferences in the same scenario).
So for starters, you can implement a toMap function that converts it to a map that GetStorage can read.
Add this to your PriceModel2 class.
Map<String, dynamic> toMap() {
return {
'name': name,
'price': price,
};
}
Then you add a named constructor in the same class so you can create your object from the Map that you stored.
PriceModel2.fromMap(Map map)
: name = map['name'],
price = map['price'];
I also suggest, regardless of whichever storage library you're using, keeping all storage related functionality, including boxes in this case, in its own class, that stores and returns whatever data you need. This way if you ever need to upgrade to Hive, ObjectBox etc... you do it in one class and not all over your app.
An example would look like this.
class Database extends GetxController {
final box = GetStorage();
Future<void> initStorage() async {
await GetStorage.init();
}
void storePriceModel(PriceModel2 model) {
box.write('model', model.toMap());
}
PriceModel2 restoreModel() {
final map = box.read('model') ?? {};
return PriceModel2.fromMap(map);
}
}
Then you would initialize your controller and storage in main.
void main() async {
await Get.put(Database()).initStorage();
runApp(MyApp());
}
An example of storing a model would look like this.
ElevatedButton(
onPressed: () {
final model = PriceModel2(name: 'test name', price: 23.0);
Get.find<Database>().storePriceModel(model);
},
child: Text('Store Model'),
),
And displaying the storage data in the UI could be done like so.
Text(Get.find<Database>().restoreModel().name)
You don't need an Obx just to display the stored data because its not an observable stream based variable.
As for displaying a list of products you do the same thing but store a list of maps instead of a single map.
If you need help with that then share how you're trying to add and store to the PriceModel2 list.
Related
In this image i created and store data on database.
demo data base for better understanding
First i get admin id from login user and i get user id from controller through which a user is created by admin and that contain random id and store user name on data base.
String idss = DateTime.now().millisecondsSinceEpoch.toString();
void dbs() {
final user = FirebaseAuth.instance.currentUser;
String? numb;
numb = user?.phoneNumber;
final dbRefrence = FirebaseDatabase.instance.ref(numb);
dbRefrence.child(numberss).child(idss).set({
'name': namess,
'title': titleController.text.toString(),
'amount': amoutController.text.toString(),
'date': DateFormat.yMMMMd().format(dateTime),
'time': timeOfDay.format(context).toString(),
}).then((value) {
TostMessage().tostMessage("Record Added");
}).onError((FirebaseException error, stackTrace) {
TostMessage().tostMessage(error.message);
});
}
But i don't know to fetch only user name from this type of structure.
I know i can fetch data from structure like adminID which has a child userID and hase a user name and other data.
i am fetching data by
final user = FirebaseAuth.instance.currentUser;
var dbShowRefrence;
String? num;
#override
void initState() {
super.initState();
num = user?.phoneNumber;
dbShowRefrence = FirebaseDatabase.instance.ref(num!).child("name");
}
in body
FirebaseAnimatedList(
query: dbShowRefrence,
itemBuilder: (context, snapshot, animation, index) {
return Card(
child: ListTile(
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => AddAll(
id,
customerNameController.text.toString(),
customerNumberController.text.toString(),
),
),
);
},
title: Text(snapshot.value.toString()),
leading: const CircleAvatar(
child: Icon(Icons.person),
),
),
);
}),
Actual data base
data displayed on my mobile.
I don't know to get only name.
Can anyone help me to fetch only name from data base?
How it looks like
I've a got bluetooth in my flutter app based on flutter_blue package (^0.8.0). I can connect with my external device and exchange the data. To read data from bluetooth following function is being called when data arrived :
void parseBleMsg(List<int> data) {
print("Data1: $data");
/* Parse the income message */
msgID = data[0];
luxValue = data[1];
print("lux: $luxValue");
print("msgid: $msgID");
}
The parseBleMsg() callback is being set by using specific flutter_blue package methods like setNotifyValue() and .value.listen() :
late BluetoothCharacteristic colsRX;
void setNotifyRX() async {
await colsRX.setNotifyValue(true);
subscription = colsRX.value.listen(
(event) {
parseBleMsg(event);
},
);
}
In one of my app pages I have got a multiple number of buttons which are a custom statefull widgets :
class MeasurementPoint extends StatefulWidget {
final int id;
final double leftPos;
final double topPos;
const MeasurementPoint(
{required this.id, required this.leftPos, required this.topPos});
#override
State<MeasurementPoint> createState() => _MeasurementPointState();
}
class _MeasurementPointState extends State<MeasurementPoint> {
bool pointState = false;
#override
Widget build(BuildContext context) {
return Positioned(
left: widget.leftPos,
top: widget.topPos,
child: ClipOval(
child: Material(
color: pointState ? Colors.green : Styles.primaryColor,
child: InkWell(
onTap: () async {
Bluetooth().bleWrite();
lastClicked = widget.id;
/* TODO : AWAIT FOR BLUETOOTH RESPONSE AND THEN CHANGE STATE */
// setState(() {
// pointState = !pointState;
// });
},
child: const SizedBox(
width: 25, height: 25, child: Icon(Icons.sensors)),
),
),
),
);
}
}
What I want to achieve
As you can see, there is the "TODO" In onTap method. Inside onTap() method I want to send the data through bluetooth to my external device (it works fine) and after that I want to await for the response and then rebuild the widget, to simply change the color of the button as an indicator that the response frame has been received.
The problem I have is that I have no idea, how to await in onTap(), or how in other way rebuilt that widget with new color when I will receive the response from bluetooth.
I wrote a code like this:
StreamBuilder(
stream: _firestore.collection("Products").where("Name", isGreaterThanOrEqualTo: SearchText.toLowerCase()).snapshots(),
builder: (BuildContext context, snapshot) {
if (snapshot.data == null) {
return const Text("No data");
}
return ListView.builder(
itemCount: snapshot.data.docs.length,
itemBuilder: (context, index) {
return Card(
child: ListTile(
title: Text(snapshot.data.docs[index].data()["Name"]),
),
);
},
);
}
),
I want to shrink the data from Firestore with .toLowerCase() or otherwise. In order to make a search system, I need to shrink the incoming data. How can I do that?
Thanks for help.
I don't understand what you mean by shrink. You mentioned toLowerCase() so this is what I think the problem is
You have a stream of product names from firestore and you want to be able to make them searchable. The user search query text might be lowercase so you want to run your search on the products from firestore(lowercased)
One way to do this is to modify the stream of products that you are getting from your firestore . You can run this on dartpad.dev/
Here is a simple example with a fake list of products. I have illustrated how to use something called a streamTransformer
// A mock list of products
final List<String> productList = [
"Airpods",
"Wallet",
"Glasses",
"Gatorade",
"Medicine"
];
// A stream that exposes the product list
Stream<String> productStream() async* {
for(var product in productList){
yield product;
}
}
void main() {
// Use a stream transformer to transform or modify the stream
StreamTransformer<String, dynamic> lowerCaser = StreamTransformer.fromHandlers(handleData: (data,sink)=> sink.add(data.toString().toLowerCase()));
// Transform the stream with the .transform function
productStream().transform(lowerCaser).listen(
(product)=>print(product)
);
}
I am doing a flutter project in which I have data stored in Firebase as follows:
Company & their recharge categories (For ex. company Asiacell has following recharge categories) :
The recharge values are stored as a number Array. I am saving this key value pair of each company (3 companies in total) in a Map.
Map phoneCompany = new Map<String, dynamic>();
String client, company, rechargeAmount;
Now I need 3 dropdowns as follows:
Selects Client or Shopkeeper - Done
Populates 3 company names if the above is only Client - Done (disables when Shopkeeper is selected)
Based on 2 above, it should populate the recharges as stored in firebase.
While I populated list of companies using:
Iterable<String> companies = phoneCompany.keys;
And
items: companies.map<DropdownMenuItem<String>>((String val) {
return DropdownMenuItem<String>(
value: val,
child: Text('${val}'),
);
}).toList(),
I am not getting any idea how to populate the list of recharges using company name selected by user. I wrote a function to select appropriate recharge list from Map using company name but fails. Though when i tried to print it (the recharges for a company) it prints fine, but the moment that list/array is being used in items, I get various errors.
My Recharge class:
class RechargeValue extends StatefulWidget {
#override
_RechargeValueState createState() => _RechargeValueState();
}
class _RechargeValueState extends State<RechargeValue> {
#override
Widget build(BuildContext context) {
return Container(
child: DropdownButton<String>(
hint: Text(
'Select Recharge Amount',
style: TextStyle(
color: Colors.red,
),
),
value: rechargeAmount,
icon: const Icon(Icons.arrow_downward),
iconSize: 55,
dropdownColor: Colors.white,
elevation: 16,
style: const TextStyle(color: Colors.deepPurple, fontSize: 18),
underline: Container(
height: 2,
color: Colors.deepPurpleAccent,
),
onChanged: (newValue) {
setState(() {
rechargeAmount = newValue;
});
print(rechargeAmount);
},
items: getRechar().map<DropdownMenuItem<String>>((String val) {
return DropdownMenuItem<String>(
value: val,
child: Text('${val}'),
);
}),
),
);
}
getRechar() {
List<String> lists = [];
if (company == null || client == 'Shopkeeper') {
lists = ['1000', '2000', '3000', '4000', '5000'];
} else {
var listCharges = phoneCompany[company] as List;
listCharges.forEach((element) {
lists.add(element.toString());
});
}
print(lists);
return lists;
}
}
I had so many errors that it is difficult to recall which approach gave what error, this is the error I get for above approach
======== Exception caught by widgets library =======================================================
The following _TypeError was thrown building RechargeValue(dirty, state: _RechargeValueState#7a12b):
type 'MappedListIterable<String, DropdownMenuItem<String>>' is not a subtype of type 'List<DropdownMenuItem<String>>?'
The interface :
Any help would be appreciated to tell me how to create 3rd dropdown using array of recharges stored in map.
I am dealing with the Futurebuilder in the Flutter, and I want to create a Future function that is going to take data from my Firebase. After that, I want to use that data inside of the text widget, so I tried to write this function to take data from firebase.
Future getData() async {
var fb = Firestore.instance;
DocumentSnapshot dr = (await fb.collection("records").document("the record").get());
return dr.toString();
}
But when I tried to use that data inside of the FutureBuilder, I am taking just Instance of 'DocumentSnapsot' text.
Here you can see my FutureBuilder codes
body: Center(
child: FutureBuilder(
future: getData(),
builder: (_ ,snapshot){
if(snapshot.connectionState==ConnectionState.waiting) {
return RaisedButton(
child: Text("loading" ),
onPressed: null,
);
}
if(snapshot.connectionState==ConnectionState.done) {
return RaisedButton(
child: Text(snapshot.data),
onPressed: () {},
);
}
return null;
}
And this is the result, after the running program:
Also, This my firebase. I just want to reach, and manipulate 0 value inside of the program.
The DocumentSnapshot toString method does not provide the data contained within the document you are trying to retrieve. To obtain the data in the document from a DocumentSnapshot, do dr.data, which returns a Map containing the fields and the associated data of those fields stored in the document. This should be done in your getData() method.
The toString method for DocumentSnapshot returns "Instance of 'DocumentSnapshot'", hence why your button is showing that instead of what you intend.