Is there a way to pull multiple values from a dropdownformfield - firebase

I am building a flutter application that has a dropdownformfield. I can get one value from the dropdown but would like to get multiple values.
my Data Model is like below
class Users {
final String uid;
final String firstName;
final String lastName;
final String phone;
Users(
{required this.uid,
required this.firstName,
required this.lastName,
required this.phone});
}
I get data from firestore and convert it into a list for the dropdown like this
final List<String> users = snapshot.data!
.map((user) => '${user.firstName} ${user.lastName}')
.toList();
and set the selected value like so:
onChanged: (val) {
setState(() {
selected = val;
});
}),
This however captures the first and the last name but I would like to get the uid as well.
Anyone know how to do this?

Related

Unhandled Exception: type 'List<dynamic>' is not a subtype of type 'List<imageObject>?' | How to input Array of Objects in Model firebase in flutter

I have been trying to actually get the data from firebase
So the actual data is :
How to get the imageUrl ?
My Try is :
class ProductModel {
String? name;
String? price;
String? discountPrice;
String? discountRate;
String? category;
String? description;
List<imageObject>? image;
ProductModel(
{required this.name,
required this.price,
this.category,
this.description,
this.discountPrice,
this.discountRate,
this.image});
ProductModel.fromMap(Map<String, dynamic> data) {
name = data['name'];
// image = data['imageUrls'][0]['url']; // To get single image i do this
image = data['imageUrls']; // but this is not working
category = data['category'];
description = data['Description'];
price = data['price'];
discountPrice = data['discountPrice'];
discountRate = data['discountRate'];
}
}
class imageObject {
final String public_id;
final String url;
imageObject({
required this.public_id,
required this.url,
});
}
It gives exception :Unhandled Exception: type 'List<dynamic>' is not a subtype of type 'List<imageObject>?'
And to access the first image i am doing,
product.image![0].url,
where product is of type ProductModel
But this is not working
You need to deserialize the imageObject json data as well. For that you need to add the factory imageObject.fromJson() constructor to your imageObject class just like you did for the ProductModel class.
Here's the code you need:
class ProductModel {
String? name;
String? price;
String? discountPrice;
String? discountRate;
String? category;
String? description;
List<imageObject>? image;
ProductModel({
required this.name,
required this.price,
this.category,
this.description,
this.discountPrice,
this.discountRate,
this.image,
});
factory ProductModel.fromJson(Map<String, dynamic> jsonData) => ProductModel(
name: jsonData['name'] as String?,
price: jsonData['price'] as String?,
category: jsonData['category'] as String?,
description: jsonData['Description'] as String?,
discountPrice: jsonData['discountPrice'] as String?,
discountRate: jsonData['discountRate'] as String?,
//Have a good look here to understand how nested list of maps are deserialized
image: (jsonData['imageUrls'] as List<dynamic>?)
?.map((e) => imageObject.fromJson(e as Map<String, dynamic>))
.toList(),
);
}
class imageObject {
final String public_id;
final String url;
imageObject({
required this.public_id,
required this.url,
});
factory imageObject.fromJson(Map<String, dynamic> jsonData) => imageObject(
public_id: jsonData['public_id'] as String,
url: jsonData['url'] as String,
);
}
What we did here is, take the data from imageUrls key as a List and map every individual element thru the json constructor of the imageObject method.
You have to map the recived list to an imageObjects list.
Create a fromMap constructor for your imageObject class
class imageObject {
final String public_id;
final String url;
imageObject({
required this.public_id,
required this.url,
});
imageObject.fromMap(Map<String, dynamic> map) => imageObject(public_id = map['public_id'], url = map['url'] );
}
Use it something like the following:
ProductModel.fromMap(Map<String, dynamic> data) {
name = data['name'];
image = data['imageUrls'].map((map) => imageObject.fromMap(map) );
category = data['category'];
description = data['Description'];
price = data['price'];
discountPrice = data['discountPrice'];
discountRate = data['discountRate'];
}
You may need to do add some casting or do some modifications to the previous code make it work, but this is the general idea.

Make a Stream able to grab datas from Cloud Firestore Flutter

I want to get datas from a collection of my cloud firestore database. I tried with a stream but it seems that it doesn't work as I'm unable to print those datas on the console and to fetch them on screen. Did I do something wrong?
Stream<List<ProductModel>> getAllProducts() =>
firebaseFirestore.collection("products").snapshots().map((query) =>
query.docs.map((item) => ProductModel.fromMap(item.data())).toList());
In case you want to know, Here is my ProductModel class, which contains the same properties asmy firestore collection
class ProductModel {
static const ID = "id";
static const IMAGE = "image";
static const NAME = "name";
static const BRAND = "brand";
static const PRICE = "price";
String? id;
String? image;
String? name;
String? brand;
double? price;
ProductModel(
{required this.id,
required this.image,
required this.name,
required this.brand,
required this.price});
ProductModel.fromMap(Map<String, dynamic> data) {
id = data[ID];
image = data[IMAGE];
name = data[NAME];
brand = data[BRAND];
price = data[PRICE].toDouble();
}
}

How to pull snapshot key & values into list through Map<>?

I've been following the official Firebase tutorial for using a real-time database: https://www.youtube.com/watch?v=sXBJZD0fBa4
I am able to pull all the data from the firebase real-time database. However, the method below to do so, provides a list of the data, with no reference to the parent keys (snapshot.key). An ideal scenario would be to have a key property within the Item class (item.key), so I can call upon it directly from the list.
class DatabaseModel {
final itemsRef = FirebaseDatabase.instance.ref().child('/Contents');
Stream<List<Items>> getItemssStream() {
final itemsStream = itemsRef.onValue;
final streamToPublish = itemsStream.map((event) {
final itemsMap = Map<String, dynamic>.from(event.snapshot.value as Map<String, dynamic>);
final itemsList = itemsMap.entries.map((element) {
return Items.fromRTDB(Map<String, dynamic>.from(element.value));
}).toList();
return itemsList;
});
return streamToPublish;
}
}
class Items{
final String item;
final String expiryDate;
final String quantity;
final String user;
Items({required this.item, required this.expiryDate, required this.quantity, required this.user});
//Mapping from real-time database
factory Items.fromRTDB(Map<String, dynamic> data) {
return Items(
item: data['item'],
expiryDate: data['exp'],
quantity: data['qty'],
user: data['user'],
);
}
}
In this code you only use the element.value of each node in your results:
return Items.fromRTDB(Map<String, dynamic>.from(element.value));
If you also want to get the key of each item, you will have to also use element.key in there and pass that to your Items object.
Something like this:
Items.fromRTDB(element.key, Map<String, dynamic>.from(element.value));
...
class Items{
final String key;
final String item;
final String expiryDate;
final String quantity;
final String user;
Items({required this.key, required this.item, required this.expiryDate, required this.quantity, required this.user});
//Mapping from real-time database
factory Items.fromRTDB(String key, Map<String, dynamic> data) {
return Items(
key: key,
item: data['item'],
expiryDate: data['exp'],
quantity: data['qty'],
user: data['user'],
);
}
}

how to display a custom list data on the app page in flutter

1[https://i.stack.imgur.com/yI2Cp.png">]1
i have tried this code to retrieve data from subcollection of the same name(userProducts) stored in many firebase documents.How do i display this data in a container on the app page ? I tried using listiew.builder but it doesnt work.
The first function
static List<products> finalProductsList = [] ;
productsList() async
{
List list_of_products = await Firestore.instance.collection("products")
.getDocuments()
.then((val) => val.documents);
for (int i=0; i<list_of_products.length; i++)
{
Firestore.instance.collection("products").document(
list_of_products[i].documentID.toString()).collection("userProducts").snapshots().listen(CreateListofProducts);
}
}
Second function
CreateListofProducts(QuerySnapshot snapshot)async
{
var docs = snapshot.documents;
for (var Doc in docs)
{
finalProductsList.add(products.fromFireStore(Doc));
}
}
CourseModel
class products {
final String prodId;
final String ownerId;
final String username;
final String price;
final String productname;
final String details;
final String color;
final String composition;
final String washandcare;
final String sizeandfit;
final String shopmediaUrl;
final String id;
final dynamic likes;
products({ this.prodId,
this.ownerId,
this.username,
this.price,
this.details,
this.productname,
this.color,
this.composition,
this.washandcare,
this.sizeandfit,
this.shopmediaUrl,
this.id,
this.likes,});
factory products.fromFireStore(DocumentSnapshot doc)
{
Map data = doc.data ;
return products(
prodId: doc['prodId'],
ownerId: doc['ownerId'],
username: doc['username'],
price: doc['price'],
productname: doc['productname'],
details: doc['details'],
shopmediaUrl: doc['shopmediaUrl'],
color:doc['color'],
composition:doc['composition'],
washandcare:doc['washandcare'],
sizeandfit:doc['sizeandfit'],
likes: doc['likes'],
);
SO if i understand you, you want to get data on multiple collections on multiple documents?
If so... you should use collecionGroup, you can learn how to use here, make sure to adjust your firestore rules.

The argument type 'int' can't be assigned to the parameter type 'Expression<int, IntType>'

I'm using moor_flutter package to interact with sqlite database on flutter app. I'm trying to parse tomorrow as in number of the day in a month. For example the date today is 24, therefore I'm parsing 25 as tomorrow inside the moor_flutter's isSmallerOrEqual() method. The purpose is to parse 25 as in runtimetype **Expression<int, IntType>** but I'm parsing it as runtimetype **int**, This is because I don't know how to convert int to Expression<int, IntType>. I've tried some different approaches but non of them are succeeding.
Below is the function where I'm doing this.
Future NearDueDate() {
// final DateTime currentDate = new DateTime.now();
var dayToday = currentDate.day;
var tommorow = int.parse(dayToday.toString()) + 1;
return (select(the_records)
..where((t_r) => t_r.due_date.day.isSmallerOrEqual(tommorow)))
.get();
}
Note the problem here is how can I convert int to Expression<int, IntType> so that I don't get any error on t_r.due_date.day.isSmallerOrEqual(tommorow)?
Thank you, posted with Love.
Sorry, I can't comment this answer.
If Expression is some kind of model. You would have to convert it by creating an instance of Expression.
Take this for example:
We have a model, User
class User {
int _id;
String _name;
User(this._name);
User.withId(this._id, this._name );
int get id => _id;
String get name => _name;
set name(String newName) {
if (newName.length <= 255) {
this._name = newName;
}
}
// Convert a User object into a Map object
Map<String, dynamic> toMap() {
var map = Map<String, dynamic>();
if (id != null) {
map['id'] = _id;
}
map['name'] = _name;
return map;
}
// Extract a User object from a Map object
User.fromMapObject(Map<String, dynamic> map) {
this._id = map['id'];
this._name = map['name'];
}
}
So this is the main point here
To create a type of User we would do something like this
user = User('John');
Now the type of user.name would be User<String>
Regularly, 'John' would just be a string. Now that it is part of the User class. It is User<String>

Resources