i am looking to have each Showing in the list of showings upload to Firestore. As of now only the first Showing in the list of Showings uploads to Firestore and the rest of the list is printed in the console but not uploaded. I appreciate any help around this. Code is below.
ShowingList Model:
class ShowingsList extends Equatable {
final List<Showing>? showingsList;
ShowingsList({required this.showingsList});
Map<String, Object> toDocument() {
for (var showing in showingsList!) {print(showing);}
for (var showing in showingsList!) {
return {
'address': showing.address!.toString(),
'showingDate': showing.showingDate!.toString(),
'client': showing.client!.toString(),
};
}throw Exception('Something went wrong');
}
#override
List<Object> get props => [showingsList!];
}
Repository
class ShowingRepository extends BaseShowingRepository {
final FirebaseFirestore _firebaseFirestore;
ShowingRepository({
FirebaseFirestore? firebaseFirestore,
}) : _firebaseFirestore = firebaseFirestore ?? FirebaseFirestore.instance;
#override
Future<void> addShowing(ShowingsList showingsList) {
return _firebaseFirestore
.collection('showings')
.add(showingsList.toDocument());
}
}
Related
In my app I have a model which consists of the store name and store image and looks like this:
class StoreModel
{
String? imageofStore;
String? storeName;
StoreModel({ this.imageofStore, this.storeName});
//data from server
factory StoreModel.fromMap(map)
{
return StoreModel(
imageofStore: map['imageofStore'],
storeName: map['storeName'],
);
}
// data to server
Map<String, dynamic> toMap(){
return{
'imageofStore': imageofStore,
'storeName': storeName,
};
}
}
and my database for stores looks like this:
to call the store name I use initstate and setState as such:
class addStore extends StatefulWidget {
const addStore({Key? key}) : super(key: key);
#override
_addStoreState createState() => _addStoreState();
}
class _addStoreState extends State<addStore> {
User ? user = FirebaseAuth.instance.currentUser;
StoreModel storebox = StoreModel();
#override
void initState()
{
super.initState();
FirebaseFirestore.instance
.collection("stores")
.doc("XQjbm665g2a2xAiiydjr")
.get()
.then((value){
this.storebox = StoreModel.fromMap(value.data());
setState(() {
});
});
}
#override
Widget build(BuildContext context) {
return Container(
child: Text("${storebox.storeName}"),
);
}
}
With this, I get the store name of the store with id XQjbm665g2a2xAiiydjr displaying but the thing is I want to get the name of all the stores. I know I need to change the .doc() but im not sure as to what I am to put in it that will start displaying all the names. Can someone please help?
By providing a document id, what you're getting is a DocumentSnapshot which is the data of a particular Document, but when you remove it, you get QuerySnapshot which is a list of the data of all the documents. So, to read all, you change your code as:
List<StoreModel> storesList = [];
FirebaseFirestore.instance
.collection("stores")
.get()
.then((value){
//Now, this value is of type QuerySnapshot unlike earlier.
if (value != null && value.docs.isNotEmpty) {
//If it comes here means the collection is not empty.
//Because this value is a list of DocumentSnapshot, We've to map it to extract documents.
//After mapping, returning it as a list and assigning it to storesList
storesList = value.docs.map((doc) => StoreModel.fromMap(doc.data())).toList();
setState(() {
});
} else {
//If it comes here means there are no documents in your collection.
//Notify User there's no data.
}
});
This code will get all the documents your collection have, but, you can limit or filter using limit or where respectively, just place .limit(int) or .where() before .get().
for model try to convert to json or you can use your either way this is just for example model
import 'dart:convert';
List<StoreModel> storeModelFromJson(String str) => List<StoreModel>.from(json.decode(str).map((x) => StoreModel.fromJson(x)));
String storeModelToJson(List<StoreModel> data) => json.encode(List<dynamic>.from(data.map((x) => x.toJson())));
class StoreModel {
StoreModel({
this.imageofStore,
this.storeName,
});
final String? imageofStore;
final String? storeName;
factory StoreModel.fromJson(Map<String, dynamic> json) => StoreModel(
imageofStore: json["imageofStore"] == null ? null : json["imageofStore"]!,
storeName: json["storeName"] == null ? null : json["storeName"]!,
);
Map<String, dynamic> toJson() => {
"imageofStore": imageofStore == null ? null : imageofStore!,
"storeName": storeName == null ? null : storeName!,
};
}
try this get all list
static Future<List<StoreModel>> getStorelist() async {
List<dynamic> list = [];
await FirebaseFirestore.instance
.collection("stores")
.get()
.then((value){
for(var x in value.docs){
final Map<String,dynamic> toMap = x.data() as Map<String,dynamic>;
/// Try to print all data first to see if fetching use log to view on terminal
log(toMap.toString());
list.add(toMap);
}
});
return list.map((e)= > StoreModel.fromJson(e)).toList();
}
as in my case to get only 1 data
static getSingleName(String? uid) async {
final result =
await FirebaseFirestore.instance
.collection("stores").doc(uid).get();
final response = result.data() as Map<String, dynamic>;
return response['storeName'].toString();
}
I am trying to fetch some menu item details such as menu name, slogan text icon, and verify data from firebase firestore using flutter but in the services of database getMenus() function, I am facing an error.
I have the following class model
import 'dart:convert';
MenuModel medicalTestModelFromJson(String str) => MenuModel.fromJson(json.decode(str));
String medicalTestModelToJson(MenuModel data) => json.encode(data.toJson());
class MenuModel {
MenuModel({
required this.title,
required this.slogan,
required this.icon,
required this.verify,
});
String title;
String slogan;
String icon;
bool verify;
factory MenuModel.fromJson(Map<String, dynamic> json) => MenuModel(
title: json["title"],
slogan: json["slogan"],
icon: json["icon"],
verify: json["verify"],
);
Map<String, dynamic> toJson() => {
"title": title,
"slogan": slogan,
"icon": icon,
"verify": verify,
};
}
And the following is the menu collection services from firebase firestore
class MenuServices{
static Future<List<MenuModel>> getMenus() async {
QuerySnapshot menuSnapshot = await FirebaseFirestore.instance.collection('homeItems').where("verify", isEqualTo: true).get();
List<MenuModel> menus =[];
Map<dynamic, dynamic> values = menuSnapshot.docs; //(***My Error is Exactly in this line which menuSnapshot.docs is not recognizing***)
values.forEach((key, values) {
menus.add(MenuModel.fromJson(values));
});
return menus;
}
}
And the error is
A value of type 'List<QueryDocumentSnapshot<Map<String, dynamic>>>' can't be assigned to a variable of type 'Map<dynamic, dynamic>
Change it to this:
class MenuServices{
static Future<List<MenuModel>> getMenus() async {
QuerySnapshot menuSnapshot = await FirebaseFirestore.instance.collection('homeItems').where("verify", isEqualTo: true).get();
List<MenuModel> menus = menuSnapshot.docs.map(
(e)=> MenuModel.fromJson(e.data() as Map<String, dynamic>)).toList();
return menus;
}
}
I used this and it worked:
void getLeituras(QuerySnapshot snapshot){
List leituras = [];
Leitura leitura;
snapshot.docs.forEach((e) {
leitura = Leitura();
leitura = Leitura.fromJson(e.data as Map<String, dynamic>);
leituras.add(leitura);
});
}
basically im struggling to create a function in my database.dart where i can call this function to display a specfic field in a specific document.
Example, i want to use Database.readUserProfileData('Profile', 'surname') to display the string/alt to a widget.
static Future<QuerySnapshot> readUserProfileData({
required String docId,
required String field,
}) async {
var ref = _mainCollection.get().then((querySnapshot) {
querySnapshot.docs.forEach((result) {
Object? data = result.data();
print(data);
});
});
}
Here is my database.dart
(please ignore the UpdateItem function as i have not configured it properly as i copied this from a template, or maybe update it for me lol sorry ;))
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/cupertino.dart';
final FirebaseFirestore _firestore = FirebaseFirestore.instance;
/* ------------------ Database Reference - Main Collection ------------------ */
final CollectionReference _mainCollection = _firestore.collection('_TestFB');
class Database {
static String? userUid;
/* -------------------------- Create User Database -------------------------- */
static Future<void> createUserDataFile({
required String uid,
required String surname,
required int mobile,
}) async {
DocumentReference documentReferencer =
_mainCollection.doc('UserData').collection(uid).doc('Profile');
Map<String, dynamic> data = <String, dynamic>{
"surname": surname,
"mobile": mobile,
};
_mainCollection
.doc('UserData')
.collection(uid)
.limit(1)
.get()
.then((snapshot) async {
if (snapshot.size == 1) {
print("**User Profile Exists");
} else {
await documentReferencer
.set(data)
.whenComplete(() => print("**New Profile Created for - " + uid))
.catchError((e) => print(e));
}
});
}
/* ------------------------- Read User Profile Data ------------------------- */
static Future<QuerySnapshot> readUserProfileData({
required String docId,
required String field,
}) async {
var ref = _mainCollection.get().then((querySnapshot) {
querySnapshot.docs.forEach((result) {
Object? data = result.data();
print(data);
});
});
}
Thanks in Advance
If you already have the document id, then just do:
static Future<DocumentSnapshot> readUserProfileData({
required String docId,
required String field,
}) async {
var ref = _mainCollection.doc(docId).get().then((snapshot) {
print(snapshot);
print(snapshot.data()[field]);
});
}
You don't need to use forEach since you are only retrieving one document and get() will have a return type Future<DocumentSnapshot>
I've tried to to fetch data from my firebase realtime database and it worked for antoher app with the same source code. But this time i think something doesn't work with my .then function. I do not receive data for building, but then 5 seconds later there is the data in my console. I know that this is asynchronous and that normally it would work, it shloud build after the init State method. Is there sth i've missed? Thx for help :)
class _HomeState extends State<Home> {
ScrollController _scrollController = new ScrollController();
List<Map<dynamic, dynamic>> _lists = [];
Future fetchList() async {
dbRef.once().then((DataSnapshot snapshot) {
Map<dynamic, dynamic> values = snapshot.value;
print(values);
_lists.clear();
values.forEach((key, values) {
_lists.add(values);
});
print(_lists);
});
return _lists;
}
final dbRef = FirebaseDatabase.instance.reference().child("spieler");
final dbRefpreise = FirebaseDatabase.instance.reference().child("preise");
#override
void initState() {
fetchList().then((value) {
setState(() {
_lists.addAll(value);
});
});
super.initState();
}
You need to await the method but since you cant await and async in iniState youll have to do this.
#override
void initState() {
getDataList();
super.initState();
}
void getDataList() async {
await fetchList().then((value) {
setState(() {
_lists.addAll(value);
});
});
}
Future fetchList() async {
await dbRef.once()..... //some code
}
I have the following problem. I'm trying to receive data from my Firestore collection called tournaments. I'm querying the database from within my DatabaseService class. That looks like the following:
class Collection<T> {
final Firestore _db = Firestore.instance;
final String path;
CollectionReference ref;
Collection({this.path}) {
ref = _db.collection(path);
}
Future<List<Tournament>> getData() async {
var snapshots = await ref.getDocuments();
return snapshots.documents
.map((doc) => Global.models[Tournament](doc.data))
.toList();
}
}
The widget implements a FutureBuilder
Widget build(BuildContext context) {
return FutureBuilder(
future: Global.tournamentRef.getData(),
builder: (BuildContext context, AsyncSnapshot snap) {
if (snap.connectionState == ConnectionState.done) {
List<Tournament> tournaments = snap.data;
...
I want to deserialize the firestore data into a Tournament object. I defined the Tournament class as this:
class Tournament {
String id;
String name;
String mode;
String owner;
int size;
Tournament({this.id, this.name, this.mode, this.owner, this.size});
factory Tournament.fromMap(Map data) {
return Tournament(
id: data["id"] ?? '',
mode: data["mode"] ?? '',
name: data["name"] ?? "group",
owner: data["owner"] ?? "",
size: data["size"] ?? 6);
}
}
The last class that is important is the globals.dart
class Global {
static final Map models = {Tournament: (data) => Tournament.fromMap(data)};
static final Collection<Tournament> tournamentRef =
Collection<Tournament>(path: "tournaments");
}
It simply specifies the collection path. I want the data to be deserialized but I don't have a clue why it isn't returning anything. I've tried querying the database in a simple old-fashioned way like
Future<dynamic> retrieveData() async {
var querySnap = await ref.getDocuments();
var list = querySnap.documents.map((snap) => snap.data);
return list;
}
That worked perfectly fine, however it doesn't help with deserialization at all. I think i missed something at some point and as you may notice I'm still a Flutter/dart beginner and some of these discussed topics are a bit too complicated to me.
I appreciate any help.
Thank you