From 5428444f299d03845e1848f88e1b45228daf5991 Mon Sep 17 00:00:00 2001 From: pm020202pm Date: Sun, 16 Jul 2023 13:46:11 +0530 Subject: [PATCH] added image upload option --- lib/accepted_tab.dart | 41 ++++----- lib/catalogue_tab.dart | 10 +-- lib/constants.dart | 19 ++-- lib/login_page.dart | 17 ++-- lib/main.dart | 2 +- lib/my_request.dart | 199 ++++++++++++++++++++++------------------- lib/user_card.dart | 20 +---- pubspec.lock | 156 ++++++++++++++++++++++++++++++-- pubspec.yaml | 2 + 9 files changed, 300 insertions(+), 166 deletions(-) diff --git a/lib/accepted_tab.dart b/lib/accepted_tab.dart index 3f3cc51..07474cc 100644 --- a/lib/accepted_tab.dart +++ b/lib/accepted_tab.dart @@ -21,11 +21,6 @@ class _AcceptedTabState extends State { acceptUsers(); } - Future _refreshAcceptedUsers() async { - await Future.delayed( - const Duration(seconds: 1)); - acceptUsers(); - } Future acceptUsers () async { QuerySnapshot querySnapshot = await FirebaseFirestore.instance.collection('Users').get(); @@ -59,26 +54,22 @@ class _AcceptedTabState extends State { @override Widget build(BuildContext context) { - return RefreshIndicator( - onRefresh: _refreshAcceptedUsers, - child: FutureBuilder>( - future: fetchFirestoreDocuments(), - builder: (BuildContext context, - AsyncSnapshot> snapshot) { - if (snapshot.connectionState == ConnectionState.waiting) { return const Text("Loading..."); } - if (snapshot.hasError) {return Text('Error: ${snapshot.error}');} - List documents = snapshot.data!; - - return ListView.builder( - itemCount: documents.length, - itemBuilder: (BuildContext context, int index) { - var name = documents[index].get('Name'); - var time = documents[index].get('Time'); - return UserCard(color: Colors.green, name: name, time: time, isMatched: true); - }, - ); - }, - ) + return FutureBuilder>( + future: fetchFirestoreDocuments(), + builder: (BuildContext context, + AsyncSnapshot> snapshot) { + if (snapshot.connectionState == ConnectionState.waiting) { return const Text("Loading..."); } + if (snapshot.hasError) {return Text('Error: ${snapshot.error}');} + List documents = snapshot.data!; + return ListView.builder( + itemCount: documents.length, + itemBuilder: (BuildContext context, int index) { + var name = documents[index].get('Name'); + var time = documents[index].get('Time'); + return UserCard(color: Colors.green, name: name, time: time, isMatched: true, imageUrl: 'assets/avatar.png',); + }, + ); + }, ); } } diff --git a/lib/catalogue_tab.dart b/lib/catalogue_tab.dart index e708174..20483a9 100644 --- a/lib/catalogue_tab.dart +++ b/lib/catalogue_tab.dart @@ -23,11 +23,9 @@ class _CatalogueTabState extends State { children: [ const Padding( padding: EdgeInsets.fromLTRB(10, 5, 0, 0), - child: Text('My Request', style: TextStyle(), textAlign: TextAlign.left,), - ), - Container( - child: MyCard(), + child: Text('My Request'), ), + MyCard(), ], ), const SizedBox(height: 20,), @@ -43,14 +41,14 @@ class _CatalogueTabState extends State { if (snapshot.connectionState == ConnectionState.waiting) { return const Text('Loading...'); } if (snapshot.hasError) {return Text('Error: ${snapshot.error}');} List documents = snapshot.data!; - return ListView.builder( itemCount: documents.length, itemBuilder: (BuildContext context, int index) { var name = documents[index].get('Name'); var time = documents[index].get('Time'); var isMatched = documents[index].get('isMatched'); - return UserCard(color: isMatched? Colors.green : null, name: name, time: time, isMatched: false); + var imageUrl = documents[index].get('imageUrl'); + return UserCard(color: isMatched? Colors.green : null, name: name, time: time, isMatched: false, imageUrl: imageUrl,); }, ); }, diff --git a/lib/constants.dart b/lib/constants.dart index 1e14617..9ed5737 100644 --- a/lib/constants.dart +++ b/lib/constants.dart @@ -2,11 +2,10 @@ import 'package:cloud_firestore/cloud_firestore.dart'; late String userUid; bool myList=false; + +/////CHECK FOR MULTIPLE REQUEST FROM SINGLE USER Future duplicates() async { - QuerySnapshot querySnapshot = await FirebaseFirestore.instance - .collection('Users') - .where("Uid", isEqualTo: userUid) - .get(); + QuerySnapshot querySnapshot = await FirebaseFirestore.instance.collection('Users').where("Uid", isEqualTo: userUid).get(); if (querySnapshot.docs.isNotEmpty) { return true; } @@ -15,20 +14,20 @@ Future duplicates() async { } } +////RETRIEVING DATA OF DOCUMENT EXCEPT USER's DOCUMENT Future> fetchFirestoreDocuments() async { - QuerySnapshot querySnapshot = await FirebaseFirestore.instance.collection('Users').get(); - // Access the documents in the query snapshot + final querySnapshot = await FirebaseFirestore.instance.collection('Users').where('Uid', isNotEqualTo: userUid).get(); List documents = querySnapshot.docs; return documents; } + void deleteContact(String documentId) { - FirebaseFirestore.instance.collection('Users').doc(documentId).delete() - .then((value) { + FirebaseFirestore.instance.collection('Users').doc(documentId).delete().then((value) { print('Contact deleted successfully.'); - }) - .catchError((error) { + }).catchError((error) { print('Failed to delete contact: $error'); }); } + diff --git a/lib/login_page.dart b/lib/login_page.dart index 2ed9c0f..5f795c9 100644 --- a/lib/login_page.dart +++ b/lib/login_page.dart @@ -13,6 +13,7 @@ class _LoginPageState extends State { final TextEditingController emailController = TextEditingController(); final TextEditingController passwordController = TextEditingController(); + /////REGISTER WITH EMAIL AND PASSWORD void registerWithEmailAndPassword(String email, String password) async { try { UserCredential userCredential = await FirebaseAuth.instance.createUserWithEmailAndPassword( @@ -25,6 +26,7 @@ class _LoginPageState extends State { } } + /////SIGN IN WITH EMAIL AND PASSWORD void signInWithEmailAndPassword(String email, String password) async { try { UserCredential userCredential = await FirebaseAuth.instance.signInWithEmailAndPassword( @@ -41,9 +43,8 @@ class _LoginPageState extends State { myList=true; }); } - print('YOUR LIST BOOL : $myList'); + print('MY LIST BOOL : $myList'); Navigator.push(context, MaterialPageRoute(builder: (context)=> MyHomePage())); - } } catch (e) { @@ -59,21 +60,15 @@ class _LoginPageState extends State { child: Center( child: Column( children: [ - TextField( - controller: emailController, - ), + TextField(controller: emailController,), const SizedBox(height: 30,), - TextField( - controller: passwordController, - ), + TextField(controller: passwordController,), TextButton( onPressed: (){registerWithEmailAndPassword(emailController.text, passwordController.text);}, child: const Text('Register') ), TextButton( - onPressed: (){ - signInWithEmailAndPassword(emailController.text, passwordController.text); - }, + onPressed: (){signInWithEmailAndPassword(emailController.text, passwordController.text);}, child: const Text('Login') ), ], diff --git a/lib/main.dart b/lib/main.dart index e166488..b4a65b8 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -14,7 +14,7 @@ class MyApp extends StatelessWidget { Widget build(BuildContext context) { return MaterialApp( routes:{ - '/homepage' : (context) => MyHomePage(), + '/homepage' : (context) => const MyHomePage(), }, title: 'TravelDost', theme: ThemeData( diff --git a/lib/my_request.dart b/lib/my_request.dart index 8425c69..b11455b 100644 --- a/lib/my_request.dart +++ b/lib/my_request.dart @@ -1,5 +1,9 @@ +import 'dart:io'; import 'package:cloud_firestore/cloud_firestore.dart'; +import 'package:firebase_storage/firebase_storage.dart'; import 'package:flutter/material.dart'; +import 'package:image_picker/image_picker.dart'; +import 'package:transport/home_page.dart'; import 'constants.dart'; class MyCard extends StatefulWidget { @@ -10,42 +14,75 @@ class MyCard extends StatefulWidget { class _MyCardState extends State { String name = ''; + String imageUrl = ''; + String myImageUrl = ''; + bool isDeleted=false; late int time = 0; late String deleteID; final TextEditingController _nameController = TextEditingController(); final TextEditingController _timeController = TextEditingController(); - Future getDocumentIdByFieldValue() async { - QuerySnapshot snapshot = await FirebaseFirestore.instance - .collection('Users') - .where('Uid', isEqualTo: userUid) - .get(); + @override + void initState() { + getDocumentIdByFieldValue(); + super.initState(); + } + + + ////UPLOADING AND GETTING URL OF IMAGE + Future selectImage() async { + ImagePicker picker = ImagePicker(); + XFile? pickedImage = await picker.pickImage(source: ImageSource.gallery); + String uniqueName = DateTime.now().microsecondsSinceEpoch.toString(); + Reference referenceImage = FirebaseStorage.instance.ref().child('images').child(uniqueName); + try { + await referenceImage.putFile(File(pickedImage!.path)); + imageUrl = await referenceImage.getDownloadURL(); + } + catch(error){ + print('CANNOT UPLOAD IMAGE AND GET URL'); + } + } + + /////RETRIEVING DATA OF A SPECIFIC DOCUMENT + Future getDocumentIdByFieldValue() async { + QuerySnapshot snapshot = await FirebaseFirestore.instance.collection('Users').where('Uid', isEqualTo: userUid).get(); if (snapshot.size > 0) { - DocumentSnapshot doc = await FirebaseFirestore.instance - .collection('Users') - .doc(snapshot.docs[0].id) - .get(); + DocumentSnapshot doc = await FirebaseFirestore.instance.collection('Users').doc(snapshot.docs[0].id).get(); if (doc.exists) { setState(() { name = doc.get('Name'); time = doc.get('Time'); deleteID = doc.id; + myImageUrl=doc.get('imageUrl'); }); - } else { + } + else { print('Document with ID does not exist.'); } - } else { + } + else { print('no_doc'); } } - @override - void initState() { - getDocumentIdByFieldValue(); - super.initState(); + /////SUBMIT DETAILS + Future submitDetails() async { + await FirebaseFirestore.instance.collection('Users').add({ + 'Name': _nameController.text, + 'Time': int.parse(_timeController.text), + 'isMatched': false, + 'imageUrl' : imageUrl, + 'Uid': userUid, + }).then((value) => print("User added")).catchError((error) => print("Failed to add user: $error")); + Navigator.pop(context); + _nameController.clear(); + _timeController.clear(); + Navigator.pushReplacement(context, MaterialPageRoute(builder: (context)=> MyHomePage())); } - void newUser() { + /////CREATE NEW REQUEST + void newRequest() { showDialog( context: context, builder: (BuildContext context) { @@ -65,35 +102,21 @@ class _MyCardState extends State { labelText: 'Time', ), ), + IconButton( + onPressed: (){selectImage();}, + icon: const Icon(Icons.image_rounded)), ], ), actions: [ TextButton( child: const Text('Cancel'), - onPressed: () { - Navigator.pop(context); - }, + onPressed: () {Navigator.pop(context);}, ), TextButton( child: const Text('Submit'), - onPressed: () async { - if (await duplicates() == false) { - await FirebaseFirestore.instance - .collection('Users') - .add({ - 'Name': _nameController.text, - 'Time': int.parse(_timeController.text), - 'isMatched': false, - 'Uid': userUid, - }) - .then((value) => print("User added")) - .catchError( - (error) => print("Failed to add user: $error")); - Navigator.pop(context); - } - _nameController.clear(); - _timeController.clear(); - }, + onPressed: () { + submitDetails(); + }, ), ], ); @@ -107,68 +130,64 @@ class _MyCardState extends State { return Padding( padding: const EdgeInsets.all(8), child: Card( - // color: color, child: Padding( - padding: const EdgeInsets.all(8.0), - child: (name == '') - ? SizedBox( - width: 0.9*screenSize.width, - child: Column( - children: [ - IconButton(onPressed: () { newUser(); }, icon: const Icon(Icons.add),), - const Text('Create new request') - ], - ), - ) - : Row( - children: [ - Container( - decoration: BoxDecoration( - color: Colors.grey[200], - shape: BoxShape.rectangle, - borderRadius: BorderRadius.circular(5), + padding: const EdgeInsets.all(8.0), + child: (name == '') + ? SizedBox( + width: 0.9*screenSize.width, + child: Column( + children: [ + IconButton(onPressed: () { newRequest(); }, icon: const Icon(Icons.add),), + const Text('Create a new request') + ], ), - height: 80, - child: Image.asset('assets/avatar.png'), - ), - const SizedBox( - width: 20, - ), - Column( - crossAxisAlignment: CrossAxisAlignment.start, + ) + : Row( children: [ - SizedBox( - width: 0.6 * screenSize.width, - child: Text('Name: $name'), - ), - const SizedBox( - height: 10, - ), - Text('Timing: $time'), - const SizedBox( - height: 10, + Container( + decoration: BoxDecoration( + color: Colors.grey[200], + shape: BoxShape.rectangle, + borderRadius: BorderRadius.circular(5), + ), + height: 80, + child: Image.network(myImageUrl), ), - Row( + const SizedBox(width: 20,), + Column( + crossAxisAlignment: CrossAxisAlignment.start, children: [ - Container( - height: 30, - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(10), - color: Colors.red[100], - ), - child: TextButton( - onPressed: () { - deleteContact(deleteID); - }, - child: const Text("Delete")), + SizedBox( + width: 0.6 * screenSize.width, + child: Text('Name: $name'), + ), + const SizedBox(height: 10,), + Text('Timing: $time'), + const SizedBox(height: 10,), + Row( + children: [ + Container( + height: 30, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(10), + color: Colors.red[100], + ), + child: TextButton( + onPressed: () { + deleteContact(deleteID); + setState(() { + name=''; + }); + }, + child: const Text("Delete")), + ), + ], ), ], ), ], - ), - ], - ), - )), + ), + )), ); } } diff --git a/lib/user_card.dart b/lib/user_card.dart index f0cc23f..cc9b74c 100644 --- a/lib/user_card.dart +++ b/lib/user_card.dart @@ -1,15 +1,15 @@ import 'package:cloud_firestore/cloud_firestore.dart'; import 'package:flutter/material.dart'; - import 'constants.dart'; class UserCard extends StatefulWidget { - UserCard({Key? key, required this.name, required this.time, required this.color, required this.isMatched}) : super(key: key); + UserCard({Key? key, required this.name, required this.time, required this.color, required this.isMatched, required this.imageUrl}) : super(key: key); final String name; final int time; final MaterialColor? color; final bool isMatched; + final String imageUrl; @override State createState() => _UserCardState(); } @@ -17,19 +17,6 @@ class UserCard extends StatefulWidget { class _UserCardState extends State { final TextEditingController _nameController = TextEditingController(); - // Future duplicates() async { - // String itemName = _nameController.text; - // QuerySnapshot querySnapshot = await FirebaseFirestore.instance - // .collection('Users') - // .where("Name", isEqualTo: itemName) - // .get(); - // if (querySnapshot.docs.isNotEmpty) { - // return true; - // } else { - // return false; - // } - // } - void newUser(int time, String name) { showDialog( context: context, @@ -80,7 +67,6 @@ class _UserCardState extends State { ); } - @override Widget build(BuildContext context) { Size screenSize = MediaQuery.of(context).size; @@ -99,7 +85,7 @@ class _UserCardState extends State { borderRadius: BorderRadius.circular(5), ), height: 80, - child: Image.asset('assets/avatar.png'), + child: Image.network(widget.imageUrl), ), const SizedBox(width: 20,), Column( diff --git a/pubspec.lock b/pubspec.lock index 32a953d..6cb333c 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -5,10 +5,10 @@ packages: dependency: transitive description: name: _flutterfire_internals - sha256: "9ebe81588e666f7e2b21309f2b5653bd9642d7f27fd0a6894278d2ff40cb9481" + sha256: "5dce45a06d386358334eb1689108db6455d90ceb0d75848d5f4819283d4ee2b8" url: "https://pub.dev" source: hosted - version: "1.3.2" + version: "1.3.4" async: dependency: transitive description: @@ -73,6 +73,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.17.0" + cross_file: + dependency: transitive + description: + name: cross_file + sha256: "0b0036e8cccbfbe0555fd83c1d31a6f30b77a96b598b35a5d36dd41f718695e9" + url: "https://pub.dev" + source: hosted + version: "0.3.3+4" cupertino_icons: dependency: "direct main" description: @@ -89,6 +97,38 @@ packages: url: "https://pub.dev" source: hosted version: "1.3.1" + file_selector_linux: + dependency: transitive + description: + name: file_selector_linux + sha256: "770eb1ab057b5ae4326d1c24cc57710758b9a46026349d021d6311bd27580046" + url: "https://pub.dev" + source: hosted + version: "0.9.2" + file_selector_macos: + dependency: transitive + description: + name: file_selector_macos + sha256: "4ada532862917bf16e3adb3891fe3a5917a58bae03293e497082203a80909412" + url: "https://pub.dev" + source: hosted + version: "0.9.3+1" + file_selector_platform_interface: + dependency: transitive + description: + name: file_selector_platform_interface + sha256: "412705a646a0ae90f33f37acfae6a0f7cbc02222d6cd34e479421c3e74d3853c" + url: "https://pub.dev" + source: hosted + version: "2.6.0" + file_selector_windows: + dependency: transitive + description: + name: file_selector_windows + sha256: "1372760c6b389842b77156203308940558a2817360154084368608413835fc26" + url: "https://pub.dev" + source: hosted + version: "0.9.3" firebase_auth: dependency: "direct main" description: @@ -117,10 +157,10 @@ packages: dependency: "direct main" description: name: firebase_core - sha256: e9b36b391690cf329c6fb1de220045e97c13784c303820cd33962319580a56c6 + sha256: "2e9324f719e90200dc7d3c4f5d2abc26052f9f2b995d3b6626c47a0dfe1c8192" url: "https://pub.dev" source: hosted - version: "2.13.1" + version: "2.15.0" firebase_core_platform_interface: dependency: transitive description: @@ -133,10 +173,34 @@ packages: dependency: transitive description: name: firebase_core_web - sha256: "8c0f4c87d20e2d001a5915df238c1f9c88704231f591324205f5a5d2a7740a45" + sha256: "0fd5c4b228de29b55fac38aed0d9e42514b3d3bd47675de52bf7f8fccaf922fa" + url: "https://pub.dev" + source: hosted + version: "2.6.0" + firebase_storage: + dependency: "direct main" + description: + name: firebase_storage + sha256: "4b747005aee0c611242cdd553f58795f51e1567d2dfd4f75692fac3f67c8c336" + url: "https://pub.dev" + source: hosted + version: "11.2.5" + firebase_storage_platform_interface: + dependency: transitive + description: + name: firebase_storage_platform_interface + sha256: c77c7b6b7d283280993c81ea8ac95552b2ae521a7bb46a95181c1482e62d1633 url: "https://pub.dev" source: hosted - version: "2.5.0" + version: "4.4.4" + firebase_storage_web: + dependency: transitive + description: + name: firebase_storage_web + sha256: "6906245579f1af225e43df0395c9d9631cb3135cbfa3521a839196d3383bb89a" + url: "https://pub.dev" + source: hosted + version: "3.6.5" flutter: dependency: "direct main" description: flutter @@ -150,6 +214,14 @@ packages: url: "https://pub.dev" source: hosted version: "2.0.1" + flutter_plugin_android_lifecycle: + dependency: transitive + description: + name: flutter_plugin_android_lifecycle + sha256: "950e77c2bbe1692bc0874fc7fb491b96a4dc340457f4ea1641443d0a6c1ea360" + url: "https://pub.dev" + source: hosted + version: "2.0.15" flutter_test: dependency: "direct dev" description: flutter @@ -224,6 +296,70 @@ packages: url: "https://pub.dev" source: hosted version: "4.0.2" + image_picker: + dependency: "direct main" + description: + name: image_picker + sha256: "6296e98782726d37f59663f0727d0e978eee1ced1ffed45ccaba591786a7f7b3" + url: "https://pub.dev" + source: hosted + version: "1.0.1" + image_picker_android: + dependency: transitive + description: + name: image_picker_android + sha256: d2bab152deb2547ea6f53d82ebca9b7e77386bb706e5789e815d37e08ea475bb + url: "https://pub.dev" + source: hosted + version: "0.8.7+3" + image_picker_for_web: + dependency: transitive + description: + name: image_picker_for_web + sha256: "869fe8a64771b7afbc99fc433a5f7be2fea4d1cb3d7c11a48b6b579eb9c797f0" + url: "https://pub.dev" + source: hosted + version: "2.2.0" + image_picker_ios: + dependency: transitive + description: + name: image_picker_ios + sha256: b3e2f21feb28b24dd73a35d7ad6e83f568337c70afab5eabac876e23803f264b + url: "https://pub.dev" + source: hosted + version: "0.8.8" + image_picker_linux: + dependency: transitive + description: + name: image_picker_linux + sha256: "02cbc21fe1706b97942b575966e5fbbeaac535e76deef70d3a242e4afb857831" + url: "https://pub.dev" + source: hosted + version: "0.2.1" + image_picker_macos: + dependency: transitive + description: + name: image_picker_macos + sha256: cee2aa86c56780c13af2c77b5f2f72973464db204569e1ba2dd744459a065af4 + url: "https://pub.dev" + source: hosted + version: "0.2.1" + image_picker_platform_interface: + dependency: transitive + description: + name: image_picker_platform_interface + sha256: "7c7b96bb9413a9c28229e717e6fd1e3edd1cc5569c1778fcca060ecf729b65ee" + url: "https://pub.dev" + source: hosted + version: "2.8.0" + image_picker_windows: + dependency: transitive + description: + name: image_picker_windows + sha256: c3066601ea42113922232c7b7b3330a2d86f029f685bba99d82c30e799914952 + url: "https://pub.dev" + source: hosted + version: "0.2.1" js: dependency: transitive description: @@ -264,6 +400,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.8.0" + mime: + dependency: transitive + description: + name: mime + sha256: e4ff8e8564c03f255408decd16e7899da1733852a9110a58fe6d1b817684a63e + url: "https://pub.dev" + source: hosted + version: "1.0.4" path: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index 97a99bc..8576b11 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -39,6 +39,8 @@ dependencies: cloud_firestore: ^4.8.0 firebase_auth: ^4.6.2 google_sign_in: ^6.1.4 + firebase_storage: ^11.2.5 + image_picker: ^1.0.1 dev_dependencies: flutter_test: