Make a Stream able to grab datas from Cloud Firestore Flutter - firebase

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();
}
}

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.

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'],
);
}
}

return a string value in flutter sqlite database

i want to get username String value for the specific deviceId from database but i am getting this error
UserName===Instance of 'Future<List<Map<String, dynamic>>>
I can insert data successfully in table, only the problem in returning the value.
here is my code:
declaring database and columns:
static final _databaseName = "MyDatabase.db";
static final _databaseVersion = 1;
static final table = 'my_table';
static final columnId = '_id';
static final columnName = 'name';
static final columnPassword = 'password';
static final columnDeviceID = 'deviceID';
///....
////...
Future _onCreate(Database db, int version) async {
await db.execute('''
CREATE TABLE $table (
$columnId INTEGER PRIMARY KEY,
$columnName STRING NOT NULL,
$columnPassword STRING NOT NULL,
$columnDeviceID STRING NOT NULL UNIQUE
)
''');
}
get Name method
Future<String> getName(String deviceid) async{
Database db = await instance.database;
String name= await columnName;
db.rawQuery('SELECT $name FROM $table WHERE $columnDeviceID = $deviceid');
return name;
}
and here is how am using getName method in app to get the value:
String user_name = await dbHelper.getName(deviceId);

Flutter Web & Firebase - Store/log information recieved from a JSON API

I would like to log/store the data received from a JSON API to Firebase as soon as the visitor accesses my website. There are no user accounts. The API returns something akin to this -only 1 post. I have implemented the data model using a JSON to Dart converter but I am confused about how to parse( figured how to retrieve it using HTTP) the JSON and store it in Firebase.
Here is the example model for reference.
import "dart:convert";
import "package:http/http.dart";
import "package: website/user.dar";
class Post {
int userId;
int id;
String title;
String body;
Post({this.userId, this.id, this.title, this.body});
Post.fromJson(Map<String, dynamic> json) {
userId = json['userId'];
id = json['id'];
title = json['title'];
body = json['body'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['userId'] = this.userId;
data['id'] = this.id;
data['title'] = this.title;
data['body'] = this.body;
return data;
}
}
class HTTP
I have already successfully set up Firebase Analytics. Currently not using any other firebase packages.
Update: Figured out how to read JSON in Dart.
import 'dart:convert';
import 'http:http.dart';
class HttpService {
static Future<IPLocation> getLocation() async {
Response response = await get(
"http://jsonplaceholder.typicode.com/posts/1");
if (response.statusCode == 200) {
final body = jsonDecode(response.body);
Post post = IPLocation.fromJson(body);
return post;
} else {
throw Exception("Failed to load Post. StatusCode: ${response.statusCode}");
}
}
}
Now the question remains - what is the best way to store this in Firebase? I would like to map them to each visitor- but I cannot set up user accounts.
Not sure if this is what you're looking for because I never used Firebase, but this is what I used to use to extract data from MySQL.
import 'dart:convert';
List<Listings> listingsFromJson(String str) =>
List<Listings>.from(json.decode(str).map((x) => Listings.fromJson(x)));
String listingsToJson(List<Listings> data) =>
json.encode(List<dynamic>.from(data.map((x) => x.toJson())));
class Listings{
Listings({
this.customerId,
this.image,
this.website,
});
String customerId;
String image;
String website;
factory Listing.fromJson(Map<String, dynamic> json) => Listings(
customerId: json["customer_id"],
image: json["image"],
website: json["website"],
);
Map<String, dynamic> toJson() => {
"customer_id": customerId,
"image": image,
"website": website,
};
}
Read Fetch and Read JSON input.
Here for clarity
import "dart:convert";
import "package:http/http.dart";
import "package: website/user.dar";
class Post {
int userId;
int id;
String title;
String body;
Post({this.userId, this.id, this.title, this.body});
Post.fromJson(Map<String, dynamic> json) {
userId = json['userId'];
id = json['id'];
title = json['title'];
body = json['body'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['userId'] = this.userId;
data['id'] = this.id;
data['title'] = this.title;
data['body'] = this.body;
return data;
}
}
Firebase
Look at setting up Anonymous users using FirebaseAuth. Then set up and log userProperties.

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.

Resources