Flutter Firebase if document doesn't exist - firebase

I just want to say if the document exists setState(the first one) else setState(the second one). I'm new in flutter so please don't hate :)
Thanks for helping!
Future<String> TerminBesetztOderFrei(String Friseur, String Tag, String Uhrzeit) async {
await Firestore.instance.collection("$Friseur/1/$Tag/1/$Uhrzeit")
.getDocuments()
.then((querySnapshot) {
querySnapshot.documents.forEach((result) {
print(result.exists);
setState(() {
terminText = "Termin nicht verfügbar!";
terminTextFarbe = Colors.red;
buttonVisible = false;
});
});
});
setState(() {
if(nameController.text != "" && telController.text != "") {
terminText = "Termin verfügbar!";
terminTextFarbe = Colors.green;
buttonVisible = true;
} else {
terminText = "Termin verfügbar! Bitte Name und Telefon eingeben!";
terminTextFarbe = Colors.green;
buttonVisible = false;
}
});
}

If you have the document Id:
final docSnapshot = await Firestore.instance
.collection("$Friseur/1/$Tag/1/$Uhrzeit")
.document(${doc_id_here})
.get();
if(docSnapshot.exists) {
setState(...)
}
else {
setState(...)
}
If you haven't
final querySnapshot = await Firestore.instance
.collection("$Friseur/1/$Tag/1/$Uhrzeit")
.getDocuments();
if(querySnapshot.documents.isNotEmpty) {
setState(...)
}

Related

Flutter firestore update values of two fields for all documents in a collection everyday

In Firestore there is a collection "students" which has two fields "date" and "onBus". I want to update these two fields everyday automatically based on the day date,
like "everyday reset "on_bus" to "0" and set "date" to today date for all students".
How can I do this for flutter app?
i try the following code but it does not work
Future<bool> resetStudentOnBus() async {
var now = DateTime.now();
var formatter = DateFormat('yyyy-MM-dd');
String formattedDate = formatter.format(now);
for (var doc in FirebaseFirestore.instance.collection('students').docs) {
if (doc?.date != formattedDate && doc?.onBus == "1") {
try {
db.collection(FirebaseConstants.pathStudentUserCollection)
.doc()
.update({"on_bus": "0", "date": formattedDate}).then((value) {
print("success");
return true;
}).catchError((onError) {
print(onError);
return false;
});
return true;
} catch (e) {
return false;
}
}
else {
return false;
}
}
}

Flutter make http api call when Firestore document changed

I'm trying to call data api when a firestore document is changed but I'm getting error: Error type 'null' is not a subtype of 'bool' with riverpod. What am I doing wrong? Thanks
final firebaseAuthProvider = Provider<FirebaseAuth>((ref) => FirebaseAuth.instance);
final authStateChangesProvider = StreamProvider<User?>((ref) => ref.watch(firebaseAuthProvider).authStateChanges());
final databaseProvider = Provider<DatabaseService?>((ref) {
final auth = ref.watch(authStateChangesProvider);
if (auth.asData?.value?.uid != null) {
return DatabaseService(uid: auth.asData!.value!.uid);
}
return null;
});
final firestoreDatabaseProvider = Provider<FirestoreDatabase?>((ref) {
final auth = ref.watch(authStateChangesProvider);
if (auth.asData?.value?.uid != null) {
return FirestoreDatabase(uid: auth.asData!.value!.uid);
}
return null;
});
final apiDataProvider2 = FutureProvider.autoDispose<ProfileUser?>((ref) {
final authUser = ref.watch(authStateChangesProvider);
final user = authUser.value;
if (user != null) {
final userValue = ref.watch(firestoreDatabaseProvider);
final dbProvider = ref.watch(databaseProvider);
var profileUser;
userValue?.getFirestoreUser().listen((event) {
profileUser = dbProvider!.getProfile();
});
if (profileUser) {
return profileUser;
} else {
return Future.value(null);
}
}
});
The problem is with profileUser; It is being returned before
var profileUser;
userValue?.getFirestoreUser().listen((event) {
profileUser = dbProvider!.getProfile();
});
if (profileUser) {
return profileUser;
} else {
return Future.value(null);
}
Try this instead:
var profileUser = (await userValue?.getFirestoreUser().first)!.getProfile();
if (profileUser) {
return profileUser;
} else {
return Future.value(null);
}

Data is not being read from firebase Realtime Database using a Stream in Flutter

since Firebase was updated I have been having some issues, first it was because now, instead of a map, an Object? is returned and that is now fixed, but I can't seem to get any data from the database. I can put it there fine but the reading is not working.
This is on my firebase_utils .dart file
FirebaseDatabase data = FirebaseDatabase.instance;
DatabaseReference database = data.ref();
Future<void> init() async {
FirebaseAuth.instance.userChanges().listen((user) {
if (user != null) {
//_loginState = ApplicationLoginState.loggedIn;
} else {
//_loginState = ApplicationLoginState.loggedOut;
}
});
if (!kIsWeb) {
data.setPersistenceEnabled(true);
data.setPersistenceCacheSizeBytes(10000000);
}
}
I have this class:
class ReservationStreamPublisher {
Stream<List<Reservation>> getReservationStream() {
final stream = database.child('reservations').onValue;
final streamToPublish = stream
.map((event) {
List<Reservation> reservationList = [];
Map<String, dynamic>.from(event.snapshot.value as dynamic)
.forEach((key, value) => reservationList.add(Reservation.fromRTDB(value)));
print(reservationList);
return reservationList;
});
return streamToPublish;
}
}
Next is my Reservation.fromRTDB
factory Reservation.fromRTDB(Map<String, dynamic> data) {
return Reservation(
pin: data['pin'],
day: data['day'],
hour: data['hour'],
duration: data['duration'],
state: data['state'],
userEmail: data['client_email'],
completed: data['completed'],
id: data['id'],
dateMade: '',
timeMade: '');
}
And this is one of the places where I am supposed to show data
Text('Slots Reservados neste dia:'),
_selectedDate != null
? StreamBuilder(
stream:
ReservationStreamPublisher().getReservationStream(),
builder: (context, snapshot) {
final tilesList = <ListTile>[];
if (snapshot.hasData) {
List reservations =
snapshot.data as List<Reservation>;
int i = 0;
do {
if (reservations.isNotEmpty) {
if (reservations[i].day !=
(DateFormat('dd/MM/yyyy')
.format(_selectedDate!))) {
reservations.removeAt(i);
i = i;
} else
i++;
}
} while (i < reservations.length);
try {
tilesList
.addAll(reservations.map((nextReservation) {
return ListTile(
leading: Icon(Icons.lock_clock),
title: Text(
"Das ${nextReservation.hour} as ${nextReservation.duration}"),
);
}));
} catch (e) {
return Text(
'Ainda nao existem reservas neste dia');
}
}
// }
if (tilesList.isNotEmpty) {
return Expanded(
child: ListView(
children: tilesList,
),
);
}
return Text('Ainda nao existem reservas neste dia');
})
: SizedBox(),
I am not getting any error at the moment, but no data is returned.This is a Reservation example on my RTDB

how to get specific id data from firebase as a map?

I am tried a lot of method for get sub collection data from[enter image description here] cloud firestore image of database
my future builder code
FutureBuilder<BasicInfoModela?>(
future: FirstoreService()
.getDoctorbasicsDetails(id: '123456'),
builder: (context, snapshot) {
switch (snapshot.connectionState) {
case ConnectionState.waiting:
return Center(child: CircularProgressIndicator());
default:
if (snapshot.hasError) {
return buildText("$snapshot");
} else if (snapshot.hasData) {
final data = snapshot.data;
print('called');
print(data);
final provider = Provider.of<WorKProvider>(context);
provider.setData(data!);
return body();
} else {
print('calledb');
return CircularProgressIndicator();
}
}
},
)),
my model code
factory BasicInfoModela.fromData(
Map<String, dynamic> data ) {
return BasicInfoModela(
userId: data['userId'],
firstName: data['firstname'],
lastName: data['lastname'],
email: data['email'],
contactnumber: data['contactnumber'],
dob: data['dod'],
gender: data['gender'],
city: data['city'],
state: data['state'],
country: data['coutry'],
experience: data['experience'],
speclization: data[''],
);
my future code for get data
Future<BasicInfoModela?> getDoctorbasicsDetails({String? id}) async {
try {
var dbdata = _usersCollectionReference.doc(id).snapshots();
String joinString = jsonDecode(dbdata.toString());
print(joinString);
return BasicInfoModela.fromData(jsonDecode(joinString));
} catch (e) {
if (e is PlatformException) {
}
}
}
how can read the sub collection?
in this code i get always null
i know its simple thing but i my case its note working
_usersCollectionReference.doc(id).snapshots()
this will return a Stream<DocumentSnapshot>
Try this code
Future<BasicInfoModela?> getDoctorbasicsDetails({String? id}) async {
try {
var dbdata = await _usersCollectionReference.doc(id).get();
return BasicInfoModela.fromData(dbdata.data);
} catch (e) {
if (e is PlatformException) {}
}
}

How to use Multi Image picker with Flutter Image Compress?

I have successfully implemented flutter multi image picker. But I want to reduce its quality. I have seen threads where its been said to use flutter_Image_compress library. But I can't seem to understand that how to implement it with multi image picker.
Multi Image picker
Future<List<Asset>> loadAssets() async {
List<Asset> resultList = List<Asset>();
String error = "No error Detected";
try {
resultList = await MultiImagePicker.pickImages(
maxImages: 10,
enableCamera: true,
selectedAssets: images,
cupertinoOptions: CupertinoOptions(takePhotoIcon: "chat"),
materialOptions: MaterialOptions(
actionBarColor: "#abcdef",
actionBarTitle: "Upload Image",
allViewTitle: "All Photos",
useDetailsView: false,
selectCircleStrokeColor: "#000000",
),
);
showInSnackBar("loading images");
print(resultList.length);
print((await resultList[0].getThumbByteData(122, 100)));
print((await resultList[0].getByteData()));
print((await resultList[0].metadata));
print("loadAssets is called");
} on Exception catch (e) {
error = e.toString();
print(error);
}
if (!mounted){
print("Not mounted");
}
else {
setState(() {
images = resultList;
_error = error;
});
}
return images;
}
Flutter image compress
void compressImage(File file) async {
final filePath = file.absolute.path;
final lastIndex = filePath.lastIndexOf(new RegExp(r'.jp'));
final splitted = filePath.substring(0, (lastIndex));
final outPath = "${splitted}_out${filePath.substring(lastIndex)}";
final compressedImage = await FlutterImageCompress.compressAndGetFile(
filePath,
outPath,
minWidth: 1000,
minHeight: 1000,
quality: 70);
}
This is what i did
Future<List<Asset>> loadAssets() async {
List<Asset> resultList = List<Asset>();
List<File> fileImageArray=[];
String error = "No error Detected";
try {
resultList = await MultiImagePicker.pickImages(
maxImages: 10,
enableCamera: true,
selectedAssets: images,
cupertinoOptions: CupertinoOptions(takePhotoIcon: "chat"),
materialOptions: MaterialOptions(
actionBarColor: "#abcdef",
actionBarTitle: "Upload Image",
allViewTitle: "All Photos",
useDetailsView: false,
selectCircleStrokeColor: "#000000",
),
);
resultList.forEach((imageAsset) async {
final filePath = await FlutterAbsolutePath.getAbsolutePath(imageAsset.identifier);
File tempFile = File(filePath);
if (tempFile.existsSync()) {
fileImageArray.add(tempFile);
}
});
compressImage(fileImageArray);
showInSnackBar("loading images");
print(resultList.length);
print((await resultList[0].getThumbByteData(122, 100)));
print((await resultList[0].getByteData()));
print((await resultList[0].metadata));
print("loadAssets is called");
} on Exception catch (e) {
error = e.toString();
print(error);
}
if (!mounted){
print("Not mounted");
}
else {
setState(() {
print('Presed1');
images = resultList;
_error = error;
});
}
return images;
}
void compressImage(fileImageArray) async {
for(var i in fileImageArray){
final filePath = i.absolute.path;
final lastIndex = i.lastIndexOf(new RegExp(r'.jp'));
final splitted = i.substring(0, (lastIndex));
final outPath = "${splitted}_out${filePath.substring(lastIndex)}";
final compressedImage = await FlutterImageCompress.compressAndGetFile(
filePath,
outPath,
minWidth: 240,
minHeight: 240,
quality: 5);
setState(() {
print('pressed2');
fileImageArray= compressedImage;
});
}
}
onPressed: () async {
List<Asset> asst = await loadAssets();
if (asst.length == 0) {
showAlert("No images selected");
}
SizedBox(height: 10,);
showInSnackBar('Images Successfully loaded');
// SnackBar snackbar = SnackBar(content: Text('Please wait, we are uploading'));
//_scaffoldKey.currentState.showSnackBar(new SnackBar(content: new Text(value)));
}
Please use this to convert List to List
List<File> fileImageArray=[];
...
resultList.forEach((imageAsset) async {
final filePath = await FlutterAbsolutePath.getAbsolutePath(imageAsset.identifier);
File tempFile = File(filePath);
if (tempFile.existsSync()) {
fileImageArray.add(tempFile);
}
});
Give fileImageArray to compressImage method.
and iterate it using for loop
void compressImage(fileImageArray) async {
for(var i in fileImageArray){
final filePath = i.absolute.path;
final lastIndex = i.lastIndexOf(new RegExp(r'.jp'));
final splitted = i.substring(0, (lastIndex));
final outPath = "${splitted}_out${filePath.substring(lastIndex)}";
final compressedImage = await FlutterImageCompress.compressAndGetFile(
filePath,
outPath,
minWidth: 240,
minHeight: 240,
quality: 5);
setState(() {
fileImageArray= compressedImage;
});
}
}
Flutter Absolute Path is not in development anymore and is not updated with the android v2 embedding. Hence I suggest to use path_provider in the below to transform an Asset to File and compress:
import 'package:multi_image_picker/multi_image_picker.dart';
import 'package:path_provider/path_provider.dart';
Future<File> compressAndUploadAssetImage(Asset asset, Reference ref) async {
final byteData = await asset.getByteData();
final tempFile = File("${(await getTemporaryDirectory()).path}/${asset.name}");
final file = await tempFile.writeAsBytes(byteData.buffer.asUint8List(byteData.offsetInBytes, byteData.lengthInBytes),);
File compressedFile = await FlutterNativeImage.compressImage(file.path, quality: 70);
return compressedFile;
}

Resources