Below is the vehicle uploading details file code that uploads details on the firebase. It uploads city, vehicle type, and phone number. I wanted to search for vehicle in the specified city. So basically it matches the details of user. For example a person wants to book vehicle in city Lahore and vehicle type Car so this should search in database if anyone uploaded details matching the description and show it to the user.
import 'dart:io';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flash_chat/constants.dart';
import 'package:flash_chat/constraints/rounded_button.dart';
import 'package:flash_chat/screens/Home.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:modal_progress_hud/modal_progress_hud.dart';
import 'package:image_picker/image_picker.dart';
class UploadingVehicle extends StatefulWidget {
static const id = 'uploading_vehicle';
#override
_UploadingVehicleState createState() => _UploadingVehicleState();
}
class _UploadingVehicleState extends State<UploadingVehicle> {
FirebaseFirestore _firestore = FirebaseFirestore.instance;
bool showSpinner = false;
static String uCity;
String description;
String phoneNumber;
String uDropdownvalue = 'Hiace';
var vehicles = ['Car','Suzuki Bolan','Hiace'];
File _image1,_image2,_image3;
String id;
final Picker = ImagePicker();
_UploadingVehicleState();
_imgFromCamera() async {
final image = await Picker.pickImage(
source: ImageSource.camera, imageQuality: 50
);
setState(() {
_image1 = File(image.path);
});
}
_imgFromGallery(String id) async {
final image = await Picker.pickImage(
source: ImageSource.gallery, imageQuality: 50
);
if(id == 'A'){
setState(() {
_image1 = File(image.path);
});
}else if(id == 'B'){
setState(() {
_image2 = File(image.path);
});
}
else if(id == 'C'){
setState(() {
_image3 = File(image.path);
});
}
}
void _showPicker(context, String id) {
showModalBottomSheet(
context: context,
builder: (BuildContext bc) {
return SafeArea(
child: Container(
child: new Wrap(
children: <Widget>[
new ListTile(
leading: new Icon(Icons.photo_library),
title: new Text('Photo Library'),
onTap: () {
_imgFromGallery(id);
Navigator.of(context).pop();
}),
new ListTile(
leading: new Icon(Icons.photo_camera),
title: new Text('Camera'),
onTap: () {
_imgFromCamera();
Navigator.of(context).pop();
},
),
],
),
),
);
}
);
}
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
appBar: AppBar(
iconTheme: IconThemeData(
color: Colors.black, //change your color here
),
title: Text('Upload vehicle'.toUpperCase(),
style: TextStyle(color: Colors.black)),
backgroundColor: Colors.yellowAccent.shade700,
leading: GestureDetector(
onTap: () {
Navigator.pop(context);
},
child: Icon(Icons.arrow_back)),
actions: [
Icon(Icons.person),
],
),
body: SafeArea(
child: Container(
child: ModalProgressHUD(
inAsyncCall: showSpinner,
child: Padding(
padding: EdgeInsets.symmetric(horizontal: 24.0),
child: Column(
//mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
SizedBox(
height: 40,
),
Material(
elevation: 18,
shadowColor: Colors.black,
child: TextField(
style: TextStyle(
color: Colors.black,
),
decoration: kRegisterTextFieldDecoration.copyWith(
prefixIcon: Icon(Icons.location_city,
color: Colors.black,
),
hintText: 'Enter City',
fillColor: Colors.white,
border: InputBorder.none,
enabledBorder: InputBorder.none,
focusedBorder: InputBorder.none,
),
autofocus: true,
onChanged: (value){
uCity = value;
},
),
),
SizedBox(
height: 40,
),
Material(
elevation: 18,
shadowColor: Colors.black,
child: TextField(
style: TextStyle(
color: Colors.black,
),
keyboardType: TextInputType.number,
decoration: kRegisterTextFieldDecoration.copyWith(
prefixIcon: Icon(
Icons.phone,
color: Colors.black,
),
hintText: 'Enter Phone Number',
fillColor: Colors.white,
border: InputBorder.none,
enabledBorder: InputBorder.none,
focusedBorder: InputBorder.none,
focusColor: Colors.blue,
),
onChanged: (value){
phoneNumber = value;
},
),
),
SizedBox(
height: 40,
),
Row(
children: <Widget>[
Text(
'Select Vehicle:',
style: TextStyle(
color: Colors.blue,
fontSize: 15,
),),
SizedBox(
width: 20,
),
Center(
child: DropdownButton<String>(
value: uDropdownvalue,
elevation: 16,
dropdownColor: Colors.white,
icon: Icon(Icons.arrow_downward,
color: Colors.black,
),
style: TextStyle(
color: Colors.black,
fontSize: 15,
),
underline: Container(
height: 1,
color: Colors.black,
),
items: vehicles.map<DropdownMenuItem<String>>((String vehicle) {
return DropdownMenuItem<String>(
value: vehicle,
child: Text(vehicle),
);
}).toList(),
onChanged: (String newValue) {
setState(() {
uDropdownvalue = newValue;
});
},
),
),
],
),
SizedBox(
height: 20,
),
Text(
'Add Description:',
style: TextStyle(
color: Colors.blue,
fontSize: 18,
),
),
Expanded(
child: Container(
child: TextField(
keyboardType: TextInputType.multiline,
maxLines: null,
decoration: InputDecoration(
enabledBorder: UnderlineInputBorder(
borderSide: BorderSide(
color: Colors.black,
)
),
),
style: TextStyle(
color: Colors.black,
),
onChanged: (value){
description=value;
},
),
),
),
Row(
children: [
Expanded(
child: buildGestureDetector(context,_image1),
),
Expanded(
child: buildGestureDetector(context,_image2),
),
Expanded(
child: buildGestureDetector(context,_image3),
),
],
),
Roundedbutton(
color: Colors.yellow,
title: 'Upload vehicle',
onPressed: () async {
setState(() {
showSpinner = true;
});
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('Details uploaded successfully')),
);
_firestore.collection('Uploading Vehicle Details').add({
'City': uCity,
'Vehicle': uDropdownvalue,
'Description' : description,
'Phone.No#' : phoneNumber,
});
Navigator.pushNamed(context, HomeScreen.id);
},
),
],
),
),
),
),
),
);
}
GestureDetector buildGestureDetector(BuildContext context, File _image) {
//GestureDetector({#required this._image});
//File _image;
return GestureDetector(
onTap: () {
_showPicker(context, 'A');
},
child: CircleAvatar(
radius: 53,
backgroundColor: Colors.black,
child: _image != null
? ClipRRect(
borderRadius: BorderRadius.circular(50),
child: Image.file(
_image,
width: 100,
height: 100,
fit: BoxFit.fitHeight,
),
)
: Container(
decoration: BoxDecoration(
color: Colors.grey[200],
borderRadius: BorderRadius.circular(50)),
width: 100,
height: 100,
child: Icon(
Icons.camera_alt,
color: Colors.grey[800],
),
),
),
);
}
}
And below is the code for the user who wants to book vehicle in his city. So it should search in firebase if the required details are present in the firebase or not. If yes it should retrieve the details from the firebase and show it to the person who's looking for it.
import 'package:flash_chat/constants.dart';
import 'package:flash_chat/constraints/rounded_button.dart';
import 'package:flutter/material.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:modal_progress_hud/modal_progress_hud.dart';
import 'package:flash_chat/screens/uploading_vehicle.dart';
class Booking extends StatefulWidget {
static const id = 'booking';
#override
_BookingState createState() => _BookingState();
}
class _BookingState extends State<Booking> {
FirebaseFirestore _firestore = FirebaseFirestore.instance;
final UploadingVehicle uv = new UploadingVehicle();
bool showSpinner = false;
String city;
String dropdownvalue = 'Hiace';
var vehicles = ['Car','Suzuki Bolan','Hiace'];
Object get uCity => null;
Object get uDropdownvalue => null;
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
appBar: AppBar(
iconTheme: IconThemeData(
color: Colors.black, //change your color here
),
title: Text('Book vehicle'.toUpperCase(),
style: TextStyle(color: Colors.black)),
backgroundColor: Colors.yellowAccent.shade700,
leading: GestureDetector(
onTap: () {
Navigator.pop(context);
},
child: Icon(Icons.arrow_back)),
actions: [
Icon(Icons.person),
],
),
body: SafeArea(
child: Container(
child: ModalProgressHUD(
inAsyncCall: showSpinner,
child: Padding(
padding: EdgeInsets.symmetric(horizontal: 24.0),
child: Column(
//mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
SizedBox(
height: 40,
),
Material(
elevation: 18,
shadowColor: Colors.black,
child: TextField(
style: TextStyle(
color: Colors.black,
),
decoration: kRegisterTextFieldDecoration.copyWith(
hintText: 'Enter City',
fillColor: Colors.white,
border: InputBorder.none,
enabledBorder: InputBorder.none,
focusedBorder: InputBorder.none,
),
onChanged: (value){
city=value;
},
),
),
SizedBox(
height: 40,
),
Row(
children: <Widget>[
Text(
'Select Vehicle:',
style: TextStyle(
color: Colors.blue,
fontSize: 15,
),),
SizedBox(
width: 20,
),
Center(
child: DropdownButton<String>(
value: dropdownvalue,
elevation: 16,
dropdownColor: Colors.white,
icon: Icon(Icons.arrow_downward,
color: Colors.black,
),
style: TextStyle(
color: Colors.black,
fontSize: 15,
),
underline: Container(
height: 1,
color: Colors.black,
),
items: vehicles.map<DropdownMenuItem<String>>((String vehicle) {
return DropdownMenuItem<String>(
value: vehicle,
child: Text(vehicle),
);
}).toList(),
onChanged: (String newValue) {
setState(() {
dropdownvalue = newValue;
});
},
),
),
],
),
Roundedbutton(
color: Colors.yellow,
title: 'Search for vehicle',
onPressed: () async {
setState(() {
showSpinner = true;
});
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('Searched')),
);
_firestore.collection('Booking Details').add({
'City': city,
'Vehicle': dropdownvalue,
});
Navigator.pushNamed(context, Booking.id);
},
),
Container(
color: Colors.white,
child: Text('Details matched',
style: TextStyle(
color: Colors.black,
fontSize: 30,
),
)
: Text(
'Details not matched',
style: TextStyle(
color: Colors.black,
fontSize: 30,
),),
),
],
),
),
),
),
),
);
}
}
How am I supposed to do this?
As far as I can tell from the massive amount of code you shared, this is the code that adds the vehicle details to the database:
_firestore.collection('Uploading Vehicle Details').add({
'City': uCity,
'Vehicle': uDropdownvalue,
'Description' : description,
'Phone.No#' : phoneNumber,
});
If you want to search that information, you can use a query such as this one:
_firestore.collection('Uploading Vehicle Details')
.where('City', isEqualTo: 'San Francisco')
.where('Vehicle', isEqualTo: 'Toyota RAV4')
.get()
.then(...);
If you want to show this in the UI, you'll want to use snapshots instead of get and wrap it in a StreamBuilder as shown in the documentation on listening to realtime changes.
Related
So I am creating a chat-app. I need to show the list of all users in the firebase by mentioning their user-name and email.
I am getting the above stated error on line 56.
Also if I remove the null check operator in the line
QuerySnapshot <Map<String, dynamic>>? searchResultSnapshot;
And replace late at the beginning it will produce late initialization error.
import 'package:chatapp/services/database.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/material.dart';
class Search extends StatefulWidget {
_Search createState() => _Search();
}
class _Search extends State<Search> {
QuerySnapshot <Map<String, dynamic>>? searchResultSnapshot;
bool isLoading = false;
bool haveUserSearched = false;
DatabaseMethods databaseMethods = new DatabaseMethods();
var searchEditingController = TextEditingController();
InitiateSearch() async {
if (searchEditingController.text.isNotEmpty) {
setState(() {
isLoading = true;
});
await databaseMethods.GetUserByUsername(searchEditingController.text)
.then((snapshot) {
searchResultSnapshot = snapshot;
print("$searchResultSnapshot");
setState(() {
isLoading = false;
haveUserSearched = true;
});
});
}
}
Widget UserList() {
return Container(
height: 500,
child: ListView.builder(
itemCount: searchResultSnapshot?.docs.length,
itemBuilder: (context, index) {
return UserTile(
searchResultSnapshot?.docs[index].data()["userName"],
searchResultSnapshot?.docs[index].data()["userEmail"],
);
}),
);
}
Widget UserTile(String? userName, String? userEmail) {
return Container(
padding: EdgeInsets.symmetric(horizontal: 24, vertical: 16),
child: Row(
children: [
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
userName!, //error here
style: TextStyle(color: Colors.white, fontSize: 16),
),
Text(
userEmail!,
style: TextStyle(color: Colors.white, fontSize: 16),
)
],
),
Spacer(),
GestureDetector(
onTap: () {
null;
},
child: Container(
padding: EdgeInsets.symmetric(horizontal: 12, vertical: 8),
decoration: BoxDecoration(
color: Colors.blue, borderRadius: BorderRadius.circular(24)),
child: Text(
"Message",
style: TextStyle(color: Colors.white, fontSize: 16),
),
),
)
],
),
);
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
titleSpacing: 0,
leading: Builder(
builder: (BuildContext context) {
return IconButton(
icon: const Icon(
Icons.arrow_back_ios,
color: Colors.white,
),
onPressed: () {
Navigator.pop(context);
});
},
),
title: Text('Search'),
),
body: Padding(
padding: const EdgeInsets.all(15.0),
child: Column(
children: [
Container(
height: 36,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.all(Radius.circular(10)),
boxShadow: [
BoxShadow(
color: Colors.black,
),
BoxShadow(
color: Colors.black,
spreadRadius: -12.0,
blurRadius: 12.0,
),
],
),
margin: EdgeInsets.symmetric(horizontal: 10.0, vertical: 8.0),
child: Padding(
padding:
const EdgeInsets.symmetric(vertical: 0, horizontal: 10.0),
child: TextFormField(
style: TextStyle(color: Colors.black),
controller: searchEditingController,
decoration: InputDecoration(
border: InputBorder.none,
hintText: 'Search',
hintStyle: TextStyle(color: Colors.grey),
icon: GestureDetector(
onTap: () {
InitiateSearch();
},
child: Icon(
Icons.search,
color: Colors.grey,
),
),
suffixIcon: IconButton(
onPressed: searchEditingController.clear,
icon: Icon(
Icons.cancel_rounded,
color: Colors.grey,
),
),
),
),
),
), //Search
SizedBox(
height: 12,
),
UserList(),
],
),
));
}
}
Here is my Database file.
import 'package:cloud_firestore/cloud_firestore.dart';
class DatabaseMethods {
GetUserByUsername(String username) async {
return await
FirebaseFirestore.instance
.collection('users')
.get()
.then((QuerySnapshot querySnapshot) {
querySnapshot.docs.forEach((doc) {
print(doc["userName"]);
});
});
}
Future<void> UploadUserInfo(userData) async {
FirebaseFirestore.instance.collection("users").add(userData).catchError((e) {
print(e.toString());
});
}
}
I would really appritiate your help on this.
You can replace below piece of code
children: [
Text(
userName!, //error here
style: TextStyle(color: Colors.white, fontSize: 16),
),
Text(
userEmail!,
style: TextStyle(color: Colors.white, fontSize: 16),
)
],
with
children: [
Text(
userName ?? "", //error here
style: TextStyle(color: Colors.white, fontSize: 16),
),
Text(
userEmail ?? "",
style: TextStyle(color: Colors.white, fontSize: 16),
)
],
In place of
return UserTile(
searchResultSnapshot?.docs[index].data()["userName"],
searchResultSnapshot?.docs[index].data()["userEmail"],
);
use this
return UserTile(
searchResultSnapshot?.docs[index].data()["userName"]??"",
searchResultSnapshot?.docs[index].data()["userEmail"]??"",
);
And replace the String? with String in (Remove ?)
Widget UserTile(String userName, String userEmail)
and use the value like the following
Text(userName,style: TextStyle(color: Colors.white, fontSize: 16),),
I am building a flutter eCommerce app. if I log in as a new user, with google, or sign up, the home page doesn't load the products... in console, It shows cloud firestore permission denied. then after I close and reopen the app, the page loads with products.
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
match /{document=**} {
allow read, write: if request.auth.uid != null;
}
}
}
the above rule is not working. but if I log in, the user logs in successfully, also the user details are added to the DB.
Login page
Error:
W/Firestore( 1298): (22.0.2) [Firestore]: Listen for
Query(target=Query(product order by
name);limitType=LIMIT_TO_FIRST) failed: Status{code=PERMISSION_DENIED, description=Missing or insufficient
permissions., cause=null}
HomePage
class _HomeoneState extends State<Homeone> {
final _key = GlobalKey<ScaffoldState>();
ProductServices _productServices = ProductServices();
List _gender = ['Current location', 'loc1', 'loc2'];
String _genderVal;
#override
Widget build(BuildContext context) {
final userProvider = Provider.of<UserProvider>(context);
final productProvider = Provider.of<ProductProvider>(context);
return Scaffold(
key: _key,
backgroundColor: white,
endDrawer: Drawer(
child: ListView(
children: <Widget>[
UserAccountsDrawerHeader(
decoration: BoxDecoration(color: red,
borderRadius: BorderRadius.only(bottomRight: Radius.circular(50),bottomLeft: Radius.circular(50)),
image: DecorationImage(
fit: BoxFit.fill,
image: NetworkImage(
'https://blogrope.com/wp-content/uploads/2013/03/happy_wallpaper_by_melaamory-d5n8m53.jpg')),
),
accountName: CustomText(
text: userProvider.userModel?.name ?? "username lading...",
color: black,
weight: FontWeight.bold,
size: 18,
),
accountEmail: CustomText(
text: userProvider.userModel?.email ?? "email loading...",
color: black,
),
),
ListTile(
onTap: () async{
await userProvider.getOrders();
changeScreen(context, OrdersScreen());
},
leading: Icon(Icons.bookmark_outlined,color: Colors.black,),
title: CustomText(text: "My orders"),
),
ListTile(
onTap: () {
Navigator.push(
context, MaterialPageRoute(builder: (context) => MyHomePage()));
},
leading: Icon(Icons.exit_to_app_outlined,color: Colors.black,),
title: CustomText(text: "Log out"),
),
ListTile(
onTap: () {
userProvider.signOut();
},
leading: Icon(Icons.exit_to_app_outlined,color: Colors.black,),
title: CustomText(text: "Log out"),
),
ListTile(
onTap: () {
AuthService().signOutGoogle();
Navigator.push(
context, MaterialPageRoute(builder: (context) => Login()));
},
leading: Icon(Icons.add),
title: CustomText(text: "Log out for google"),
),
],
),
),
body:
SafeArea(
child: ListView(
physics: AlwaysScrollableScrollPhysics(),
children: <Widget>[
// Custom App bar
Column(
children: <Widget>[
Container(
padding: const EdgeInsets.all(5.0),
child: Row(
children: [
Padding(
padding: const EdgeInsets.all(8.0),
child: Text('Hi',style: TextStyle(color: Colors.black),)),
Padding(
padding: const EdgeInsets.all(4.0),
child: Text(
userProvider.userModel?.name ?? "wait...",
),
),
Container(
margin: EdgeInsets.all(14),
child: Padding(
padding: const EdgeInsets.fromLTRB(200.0,0,0,0),
child: Align(
alignment: Alignment.topRight,
child: GestureDetector(
onTap: (){
changeScreen(context, CartScreen());
},
child: Icon(Icons.shopping_cart))),
),
),
],
),
),
Container(
margin: EdgeInsets.fromLTRB(280, 0, 0, 0),
child: GestureDetector(
onTap: () {
_key.currentState.openEndDrawer();
},
child: Icon(Icons.menu)),
),
Padding(
padding: const EdgeInsets.all(5.0),
child: Align(
alignment: Alignment.topLeft,
child: Text(
'Delivering to',
style: TextStyle(
color: Colors.grey,
),
),
),
),
Container(
padding: EdgeInsets.all(8),
margin: EdgeInsets.all(4),
decoration: BoxDecoration(
border: Border.all(color: Colors.transparent),
borderRadius: BorderRadius.all(Radius.circular(20)),
color: Colors.white,
),
child: DropdownButton(
hint: Text('Current location'),
dropdownColor: Colors.white,
value: _genderVal,
isExpanded: true,
onChanged: (value) {
setState(() {
_genderVal = value;
});
},
items: _gender.map((value) {
return DropdownMenuItem(
value: value,
child: Text(value),
);
}).toList(),
),
),
],
),
// Search Text field
// Search(),
Container(
decoration: BoxDecoration(
color: white,
borderRadius: BorderRadius.only(
bottomRight: Radius.circular(24),
bottomLeft: Radius.circular(24))),
child: Padding(
padding: const EdgeInsets.only(
top: 5, left: 14, right: 14, bottom: 14),
child: Container(
decoration: BoxDecoration(
color: grey.withOpacity(0.2),
borderRadius: BorderRadius.circular(15),
),
child: ListTile(
leading: Icon(
Icons.search,
color: black,
),
title: TextField(
textInputAction: TextInputAction.search,
onSubmitted: (pattern)async{
await productProvider.search(productName: pattern);
changeScreen(context, ProductSearchScreen());
},
decoration: InputDecoration(
hintText: "Search...",
border: InputBorder.none,
),
),
),
),
),
),
// featured products
ListTile(
title: Text('Menu of the Day',
style: TextStyle(color: Colors.black, fontSize: 18),),
trailing: Text('View all', style: TextStyle(color: Colors.red),
),
),
FeaturedProducts(),
ListTile(
title: Text('Highly rated foods',
style: TextStyle(color: Colors.black, fontSize: 18),),
trailing: Text('View all', style: TextStyle(color: Colors.red),
),
),
FeaturedProductsone(),
// recent products
Row(
children: <Widget>[
Padding(
padding: const EdgeInsets.all(14.0),
child: Container(
alignment: Alignment.centerLeft,
child: new Text('Recent products')),
),
],
),
Column(
children: productProvider.products
.map((item) => GestureDetector(
child: ProductCard(
product: item,
),
))
.toList(),
),
],
),
),
);
}
}
Login
final userProvider = Provider.of<UserProvider>(context);
return Scaffold(
key: _key,
body:userProvider.status == Status.Authenticating ? Loading() : Form(
key: _formKey,
child: ListView(
children: <Widget>[
Container(
padding: EdgeInsets.all(20.0),
margin: EdgeInsets.all(30),
child: Center(
child: Text(
'Login',
style: TextStyle(
fontSize: 30,
fontWeight: FontWeight.w500,
),
),
),
),
Container(
child: Center(
child: Text(
'Add details to login',
style: TextStyle(
fontSize: 15,
),
),
),
),
Container(
padding: EdgeInsets.all(20),
child: TextFormField(
controller: _email,
keyboardType: TextInputType.emailAddress,
decoration: InputDecoration(
suffixIcon: Icon(Icons.email),
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(color: Colors.transparent),
borderRadius: BorderRadius.all(Radius.circular(20)),
),
hintText: 'Your Email',
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(color: Colors.blueAccent),
borderRadius: BorderRadius.all(Radius.circular(20)),
),
filled: true,
fillColor: Colors.grey[200],
),
validator: (value) {
if (value.isEmpty) {
Pattern pattern =
r'^(([^<>()[\]\\.,;:\s#\"]+(\.[^<>()[\]\\.,;:\s#\"]+)*)|(\".+\"))#((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$';
RegExp regex = new RegExp(pattern);
if (!regex.hasMatch(value))
return 'Please make sure your email address is valid';
else
return null;
}
},
),
),
Container(
padding: EdgeInsets.all(20),
child: TextFormField(
controller: _password,
obscureText: true,
decoration: InputDecoration(
suffixIcon: Icon(Icons.vpn_key_sharp),
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(color: Colors.transparent),
borderRadius: BorderRadius.all(Radius.circular(20)),
),
hintText: 'Password',
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(color: Colors.blueAccent),
borderRadius: BorderRadius.all(Radius.circular(20)),
),
filled: true,
fillColor: Colors.grey[200],
),
validator: (value) {
if (value.isEmpty) {
return "The password field cannot be empty";
} else if (value.length < 6) {
return "the password has to be at least 6 characters long";
}
return null;
},
),
),
Container(
padding: EdgeInsets.all(40),
child: RaisedButton(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(40.0),
),
color: Color(0xfffd44323),
child: Text('Login',
style: TextStyle(
fontSize: 20,
)),
textColor: Colors.white,
onPressed: () async {
// _loginUser(type: LoginType.email,email:_emailController.text, password:_passwordController.text,context: context);
if(_formKey.currentState.validate()){
if(!await userProvider.signIn(_email.text, _password.text))
_key.currentState.showSnackBar(SnackBar(content: Text("Failure")));
return;
}
changeScreenReplacement(context, HomePage());
},
),
),
InkWell(
child: Container(
child: Center(
child: Text(
'Forgot password',
style: TextStyle(
fontSize: 15,
),
),
),
),
onTap: (){
// Navigator.push(
// context, MaterialPageRoute(builder: (context) => Dashone()));
},
),
Container(
margin: EdgeInsets.all(35.0),
child: Center(
child: Text(
'or Login with ',
style: TextStyle(
fontSize: 15,
),
),
),
),
Container(
padding: EdgeInsets.all(5),
margin: EdgeInsets.all(20.0),
decoration: BoxDecoration(
border: Border.all(color: Colors.transparent),
borderRadius: BorderRadius.all(Radius.circular(34)),
color: Color(0xfff3680c1),
),
child: Center(
child: ListTile(
leading: SvgPicture.asset('assets/facebook.svg',
color: Colors.white),
title: Center(
child: Text(
'Login with facebook',
style: TextStyle(
color: Colors.white,
fontSize: 17,
),
)),
),
),
),
Container(
padding: EdgeInsets.all(5),
margin: EdgeInsets.all(20.0),
decoration: BoxDecoration(
border: Border.all(color: Colors.transparent),
borderRadius: BorderRadius.all(Radius.circular(34)),
color: Color(0xfffd44323),
),
child: Center(
child: InkWell(
child: ListTile(
leading: SvgPicture.asset(
'assets/google-plus.svg',
color: Colors.white,
height: 25.0,
width: 25.0,
),
title: Center(
child: InkWell(
child: Container(
child: Text(
'Login with Google',
style: TextStyle(
color: Colors.white,
fontSize: 17,
),
),
),
onTap: () async {
FirebaseAuth _auth = FirebaseAuth.instance;
User user = await AuthService().signInWithGoogle();
print(user);
if (user == null) {
_userServices.createUser({
"name": _auth.currentUser.displayName,
"photo": _auth.currentUser.photoURL,
"email": _auth.currentUser.email,
"uid": _auth.currentUser.uid,
"votes": votes,
"trips": trips,
"rating": rating,
});
// _userServices.createUser(
//
//
// );
// 5s over, navigate to a new page
Navigator.pushReplacement(
context, MaterialPageRoute(
builder: (context) => HomePage()));
}
},
),
)
),
),
),
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
child: Center(
child: Text(
'Don\'t have an Account?',
style: TextStyle(
fontSize: 15,
),
),
),
),
InkWell(
child: Container(
padding: EdgeInsets.all(10.0),
child: Center(
child: Text(
'Sign up',
style: TextStyle(
fontSize: 15,
fontWeight: FontWeight.bold,
color: Color(0xfffd44323),
),
),
),
),
onTap: () {
changeScreen(context, SignUp());
},
),
],
),
],
),
),
);
}
}
After restaring the app
my signup.dart file:
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
class SignUp extends StatefulWidget {
#override
_SignUpState createState() => _SignUpState();
}
class _SignUpState extends State<SignUp> {
final FirebaseAuth firebaseAuth = FirebaseAuth.instance;
final _formKey = GlobalKey<FormState>();
TextEditingController _emailTextController = TextEditingController();
TextEditingController _passwordTextController = TextEditingController();
TextEditingController _nameTextController = TextEditingController();
TextEditingController _confirmPasswordTextController =
TextEditingController();
String gender;
String groupValue = "Erkek";
bool loading = false;
#override
Widget build(BuildContext context) {
return Scaffold(
body: Stack(
children: <Widget>[
Image.asset(
'images/backg.jpg',
fit: BoxFit.fill,
width: double.infinity,
height: double.infinity,
),
Container(
color: Colors.black.withOpacity(0.4),
width: double.infinity,
height: double.infinity,
),
Padding(
padding: const EdgeInsets.only(top: 200.0),
child: Center(
child: Form(
key: _formKey,
child: ListView(
children: <Widget>[
Padding(
padding:
const EdgeInsets.fromLTRB(14.0, 8.0, 14.0, 8.0),
child: Material(
borderRadius: BorderRadius.circular(20.0),
color: Colors.white.withOpacity(0.4),
elevation: 0.0,
child: Padding(
padding: const EdgeInsets.only(left: 12.0),
child: ListTile(
title: TextFormField(
controller: _passwordTextController,
decoration: InputDecoration(
hintText: "Ad Soyad",
icon: Icon(Icons.person),
border: InputBorder.none
),
// ignore: missing_return
validator: (value) {
if (value.isEmpty) {
return "İsim boşluğu doldurulmalıdır.";
}
return null;
},
// ignore: missing_return
),
trailing: Icon(Icons.remove_red_eye),
),
),
),
),
Padding(
padding:
const EdgeInsets.fromLTRB(14.0, 8.0, 14.0, 8.0),
child: Material(
borderRadius: BorderRadius.circular(20.0),
color: Colors.white.withOpacity(0.4),
elevation: 0.0,
child: Padding(
padding: const EdgeInsets.only(left: 12.0),
child: TextFormField(
controller: _emailTextController,
decoration: InputDecoration(
hintText: "Email",
icon: Icon(Icons.email),
border: InputBorder.none
),
// ignore: missing_return
validator: (value) {
if (value.isEmpty) {
Pattern pattern =
r'^(([^<>()[]\.,;:\s#"]+(.[^<>()[]\.,;:\s#"]+)*)|(".+"))#(([[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}])|(([a-zA-Z-0-9]+.)+[a-zA-Z]{2,}))$';
RegExp regex = new RegExp(pattern);
if (!regex.hasMatch(value))
return "Lütfen geçerli bir mail adresi giriniz.";
else
return null;
}
}),
),
),
),
Padding(
padding: const EdgeInsets.fromLTRB(14.0, 8.0, 14.0, 8.0),
child: new Container(
color: Colors.white.withOpacity(0.4),
child: Row(
children: <Widget>[
Expanded(
child: ListTile(
title: Text(
"Erkek",
textAlign: TextAlign.end ,
style: TextStyle(color: Colors.white),
),
trailing: Radio(value: "Erkek", groupValue: groupValue, onChanged: (e)=>valueChanged(e)),
)),
Expanded(
child: ListTile(
title: Text(
"Kadın",
textAlign: TextAlign.end ,
style: TextStyle(color: Colors.white),
),
trailing: Radio(value: "Kadın", groupValue: groupValue, onChanged: (e)=>valueChanged(e)),
)),
],
),
),
),
Padding(
padding:
const EdgeInsets.fromLTRB(14.0, 8.0, 14.0, 8.0),
child: Material(
borderRadius: BorderRadius.circular(20.0),
color: Colors.white.withOpacity(0.4),
elevation: 0.0,
child: Padding(
padding: const EdgeInsets.only(left: 12.0),
child: ListTile(
title: TextFormField(
controller: _passwordTextController,
obscureText: true,
decoration: InputDecoration(
hintText: "Şifre",
icon: Icon(Icons.lock_outline),
border: InputBorder.none
),
// ignore: missing_return
validator: (value) {
if (value.isEmpty) {
return "Şifre boşluğu doldurulmalıdır.";
} else if (value.length < 6) {
return "Şifre 6 haneden uzun olmalı!";
}
return null;
},
// ignore: missing_return
),
trailing : IconButton(icon: Icon(Icons.remove_red_eye), onPressed: (){})
),
),
),
),
Padding(
padding:
const EdgeInsets.fromLTRB(14.0, 8.0, 14.0, 8.0),
child: Material(
borderRadius: BorderRadius.circular(20.0),
color: Colors.white.withOpacity(0.4),
elevation: 0.0,
child: Padding(
padding: const EdgeInsets.only(left: 12.0),
child: ListTile(
title : TextFormField(
controller: _confirmPasswordTextController,
obscureText: true,
decoration: InputDecoration(
hintText: "Şifreyi Doğrula",
icon: Icon(Icons.lock_outline),
border: InputBorder.none
),
// ignore: missing_return
validator: (value) {
if (value.isEmpty) {
return "Şifre boşluğu doldurulmalıdır.";
} else if (value.length < 6) {
return "Şifre 6 haneden uzun olmalı!";
}else if (_passwordTextController != value){
return "Şifreler uyuşmuyor.";
}
return null;
},
// ignore: missing_return
),
trailing : IconButton(icon: Icon(Icons.remove_red_eye), onPressed: (){}),
),
),
),
),
Padding(
padding:
const EdgeInsets.fromLTRB(12.0, 8.0, 12.0, 8.0),
child: Material(
borderRadius: BorderRadius.circular(20.0),
color: Colors.red.withOpacity(0.8),
elevation: 0.0,
child: MaterialButton(
onPressed: () {
validateForm();
},
minWidth: MediaQuery.of(context).size.width,
child: Text(
"Kayıt Ol",
textAlign: TextAlign.center,
style: TextStyle(
color: Colors.white,
fontWeight: FontWeight.bold,
fontSize: 15.0),
),
)),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: InkWell(
onTap: () {
Navigator.pop(context);
},
child: Text(
"Giriş Yap",
textAlign: TextAlign.center,
style: TextStyle(color: Colors.red),
))),
],
)),
),
),
Visibility(
visible: loading ?? true,
child: Center(
child: Container(
alignment: Alignment.center,
color: Colors.white.withOpacity(0.9),
child: CircularProgressIndicator(
valueColor: AlwaysStoppedAnimation<Color>(Colors.red),
),
),
))
],
),
);
}
valueChanged(e) {
setState(() {
if (e == "Erkek") {
groupValue = e;
gender = e;
} else if (e == "Kadın") {
groupValue = e;
gender = e;
}
});
}
void validateForm() async{
FormState formState = _formKey.currentState;
if(formState.validate()){
User user = await firebaseAuth.currentUser;
if(user == null){
firebaseAuth.createUserWithEmailAndPassword(email: _emailTextController, password: _passwordTextController).then((user) => {
});
}
}
}
}
My Showing errors.
Performing hot reload...
Syncing files to device sdk gphone x86...
lib/pages/signup.dart:276:60: Error: The argument type 'TextEditingController' can't be assigned to the parameter type 'String'.
'TextEditingController' is from 'package:flutter/src/widgets/editable_text.dart' ('/C:/src/flutter/packages/flutter/lib/src/widgets/editable_text.dart').
firebaseAuth.createUserWithEmailAndPassword(email: _emailTextController, password: _passwordTextController).then((user) => {
^
lib/pages/signup.dart:276:92: Error: The argument type 'TextEditingController' can't be assigned to the parameter type 'String'.
'TextEditingController' is from 'package:flutter/src/widgets/editable_text.dart' ('/C:/src/flutter/packages/flutter/lib/src/widgets/editable_text.dart').
firebaseAuth.createUserWithEmailAndPassword(email: _emailTextController, password: _passwordTextController).then((user) => {
^
==========NEW ERRORRR=================
void validateForm() async {
FormState formState = _formKey.currentState;
if (formState.validate()) {
User user = await firebaseAuth.currentUser;
if (user == null) {
firebaseAuth
.createUserWithEmailAndPassword(
email: _emailTextController.text,
password: _passwordTextController.text)
.then((user) => {
_userServices.createUser(
{
"username": _nameTextController.text,
"email": user.email
}
)
});
}
}
}
}
Use _emailTextController.text instead of just _emailTextController.
Everytime when I try to use loggegInUser property it returns null please help me to solve this issue
getCurrent() methods works properly and prints user email and password but I can not acces this variables in Build Widget.
class _ProfilePageState extends State<ProfilePage> {
final _auth = FirebaseAuth.instance;
FirebaseUser loggedInUser;
String uid;
var url;
var userProfilePhotoUrl;
int currentPageIndex = 2;
CircularBottomNavigationController _navigationController =
new CircularBottomNavigationController(2);
List<TabItem> tabItems = List.of([
new TabItem(Icons.home, "Home", Colors.blue,
labelStyle: TextStyle(fontWeight: FontWeight.normal)),
new TabItem(Icons.add, "Let's Party", Colors.orange,
labelStyle: TextStyle(color: Colors.red, fontWeight: FontWeight.bold)),
new TabItem(Icons.person, "Reports", Colors.red),
]);
#override
void initState() {
super.initState();
getCurrentUser();
}
void getCurrentUser() async {
try {
final user = await _auth.currentUser();
if (user != null) {
loggedInUser = user;
uid = user.uid;
print(loggedInUser.email);
print(uid);
}
} catch (e) {
print(e);
}
}
void changePage(int index) {
setState(() {
currentPageIndex = index;
});
}
Future<FirebaseImage> getFirebaseProfilPhoto() async {
try {
final user = await _auth.currentUser();
if (user != null) {
loggedInUser = user;
uid = user.uid;
print(loggedInUser.email);
print(uid);
return FirebaseImage(
'gs://homeparty-68792.appspot.com/user_profile_images/${loggedInUser.uid}.png');
}
} catch (e) {
print(e);
}
}
#override
Widget build(BuildContext context) {
setState(() {
getCurrentUser();
});
return Scaffold(
appBar: AppBar(
title: Text('furkanakguun'),
),
body: Builder(
builder: (context) => Container(
color: Colors.black,
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
SizedBox(
height: 20.0,
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
CircleAvatar(
backgroundColor: Colors.black,
backgroundImage: FirebaseImage(
'gs://homeparty-68792.appspot.com/user_profile_images/${loggedInUser.uid}.png'),
// FirebaseImage(
// 'gs://homeparty-68792.appspot.com/user_profile_images/$uid.png'),
//backgroundImage: Image.network(userProfilePhotoUrl),
radius: 100,
),
Padding(
padding: EdgeInsets.only(top: 60.0),
child: IconButton(
icon: Icon(
FontAwesomeIcons.camera,
size: 30.0,
),
focusColor: Colors.white,
color: Colors.deepPurple,
onPressed: () {
print('asd');
Navigator.pushNamed(context, 'image_uploader');
},
),
),
],
),
Divider(),
SizedBox(
height: 20.0,
),
Row(
children: <Widget>[
Card(
color: Colors.grey[900],
margin: EdgeInsets.symmetric(horizontal: 10.0),
child: Icon(Icons.person),
),
Card(
color: Colors.grey[900],
margin:
EdgeInsets.symmetric(horizontal: 10.0, vertical: 7.0),
child: Container(
child: Column(
children: <Widget>[
Align(
alignment: Alignment.centerLeft,
child: Text('Furkan Akgün',
style: TextStyle(
color: Colors.white,
fontSize: 20.0,
fontWeight: FontWeight.bold)),
),
],
),
),
),
],
),
SizedBox(
height: 20.0,
),
Row(
children: <Widget>[
Card(
color: Colors.grey[900],
margin: EdgeInsets.symmetric(horizontal: 10.0),
child: Icon(Icons.location_on),
),
Card(
color: Colors.grey[900],
margin:
EdgeInsets.symmetric(horizontal: 10.0, vertical: 7.0),
child: Container(
child: Column(
children: <Widget>[
Align(
alignment: Alignment.centerLeft,
child: Text('Ankara',
style: TextStyle(
color: Colors.white,
fontSize: 20.0,
fontWeight: FontWeight.bold)),
),
],
),
),
),
],
),
SizedBox(
height: 20.0,
),
Row(
children: <Widget>[
Card(
color: Colors.grey[900],
margin: EdgeInsets.symmetric(horizontal: 10.0),
child: Icon(Icons.rate_review),
),
Card(
color: Colors.grey[900],
margin:
EdgeInsets.symmetric(horizontal: 10.0, vertical: 7.0),
child: Container(
child: SmoothStarRating(
spacing: 2.0,
allowHalfRating: true,
starCount: 5,
rating: 4.5,
size: 20,
color: Colors.yellow,
borderColor: Colors.white,
isReadOnly: true,
)),
),
],
),
SizedBox(
height: 20.0,
),
SizedBox(
height: 40.0,
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
RaisedButton(
color: Colors.deepPurple[900],
onPressed: () {
//uploadPic(context);
},
elevation: 4.0,
splashColor: Colors.blueGrey,
child: Text(
'Edit',
style: TextStyle(color: Colors.white, fontSize: 16.0),
),
),
],
)
],
),
),
),
bottomNavigationBar: CircularBottomNavigation(
tabItems,
barBackgroundColor: Colors.deepPurple[900],
controller: _navigationController,
selectedCallback: (int selectedPos) {
if (selectedPos == 0) {
Navigator.pushNamed(context, 'dashboard_screen');
}
if (selectedPos == 2) {
Navigator.pushNamed(context, 'user_profile');
}
},
),
);
}
}
enter image description here
ERROR TYPE
Exception has occurred.
NoSuchMethodError (NoSuchMethodError: The getter 'uid' was called on null.
Receiver: null
Tried calling: uid)
My guess is that the error comes from this code in your build method:
FirebaseImage('gs://homeparty-68792.appspot.com/user_profile_images/${loggedInUser.uid}.png')
This is because the UI may be built before the user sign-in is completed.
To prevent this from happening you need to handle the fact that the user may not be signed in, in your build code too, for example by skipping the rendering of their profile image:
backgroundImage: loggedInUser != null ?
FirebaseImage('gs://homeparty-68792.appspot.com/user_profile_images/${loggedInUser.uid}.png') :
Text("Loading...")
I want to get the value of (profile.imgUrl) from Firestore but I get error:
The getter 'imgUrl' was called on null.
Receiver: null
Tried calling: imgUrl
Although the user is signed in and I can get the data in the home page but when I navigate to Account page it gives me this error.
class Account extends StatelessWidget {
final Profile profile;
Account({this.profile});
final AuthService _auth = AuthService();
#override
Widget build(BuildContext context) {
print(profile.imgUrl);
return StreamProvider<List<Profile>>.value(
value: DatabaseService().profiles,
child: Scaffold(
body: Stack(
children: <Widget>[
ClipPath(
child: Container(
color: Colors.green.withOpacity(0.8),
),
clipper: getClipper(),
),
Positioned(
width: 400,
top: MediaQuery.of(context).size.height / 5,
child: Column(
children: <Widget>[
Container(
width: 150.0,
height: 150.0,
decoration: BoxDecoration(
color: Colors.green,
image: DecorationImage(
image: NetworkImage(profile.imgUrl),
fit: BoxFit.cover),
borderRadius: BorderRadius.all(Radius.circular(75.0)),
boxShadow: [
BoxShadow(blurRadius: 7.0, color: Colors.black)
]),
),
SizedBox(
height: 90.0,
),
Text(
'Alex Ali',
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 30.0,
fontFamily: 'Montserrat',
letterSpacing: 1.5),
),
SizedBox(
height: 15.0,
),
Text(
'New Seller',
style: TextStyle(
fontStyle: FontStyle.italic,
fontSize: 17.0,
color: Colors.green),
),
SizedBox(
height: 25,
),
Container(
height: 30.0,
width: 95.0,
child: Material(
borderRadius: BorderRadius.circular(20.0),
shadowColor: Colors.greenAccent,
color: Colors.green,
elevation: 7.0,
child: GestureDetector(
onTap: () {
print(profile.imgUrl);
},
child: Center(
child: Text(
'Edit Name',
style: TextStyle(color: Colors.white),
),
),
),
),
),
SizedBox(
height: 25,
),
Container(
height: 30.0,
width: 95.0,
child: Material(
borderRadius: BorderRadius.circular(20.0),
shadowColor: Colors.redAccent,
color: Colors.red,
elevation: 7.0,
child: GestureDetector(
onTap: () async {
await _auth.signOut();
},
child: Center(
child: Text(
'Log out',
style: TextStyle(color: Colors.white),
),
),
),
),
)
],
),
)
],
)
),
);
}
}
class getClipper extends CustomClipper<Path> {
#override
Path getClip(Size size) {
var path = new Path();
path.lineTo(0.0, size.height / 1.9);
path.lineTo(size.width + 125, 0.0);
path.close();
return path;
}
#override
bool shouldReclip(CustomClipper<Path> oldClipper) {
return true;
}
}
and that is Home page code:
class Home extends StatefulWidget {
#override
_Home createState() => _Home();
}
class _Home extends State<Home> {
final AuthService _auth = AuthService();
#override
Widget build(BuildContext context) {
return StreamProvider<List<Profile>>.value(
value: DatabaseService().profiles,
child: Scaffold(
body: SafeArea(
child: ListView(
padding: EdgeInsets.symmetric(vertical: 30.0),
children: <Widget>[
Padding(
padding: EdgeInsets.only(left: 20.0, right: 120.0),
child: Text(
"What would you like to find?",
style: TextStyle(fontSize: 30, fontWeight: FontWeight.bold),
),
),
SizedBox(height: 20.0),
SizedBox(
height: 20.0,
),
SizedBox(height: 500, child: ProfileList()),
],
),
),
),
);
}
}
Here is the code that opens Account page through BottomNavigationBar:
class Wrapper extends StatefulWidget {
#override
_WrapperState createState() => _WrapperState();
}
class _WrapperState extends State<Wrapper> {
int _currentTab = 0;
final _page = [
Home(),
Search(),
Account(),
];
#override
Widget build(BuildContext context) {
final user = Provider.of<User>(context);
print(user);
if (user == null) {
return Authenticate();
} else {
return Scaffold(
body: _page[_currentTab],
bottomNavigationBar: BottomNavigationBar(
currentIndex: _currentTab,
onTap: (int value) {
setState(() {
_currentTab = value;
});
},
items: [
BottomNavigationBarItem(
icon: Icon(
Icons.home,
size: 30.0,
),
title: SizedBox.shrink()),
BottomNavigationBarItem(
icon: Icon(
Icons.search,
size: 30.0,
),
title: SizedBox.shrink()),
BottomNavigationBarItem(
icon: Icon(
Icons.person,
size: 30.0,
),
title: SizedBox.shrink(),
)
]),
);
}
}
}
You need to pass a Profile as a parameter when Account is created.
That should be done dynamically, so you can't use a fixed list.
Instead of doing this:
final _page = [
Home(),
Search(),
Account(),
];
Scaffold(
body: _page[_currentTab],
// ...
)
You should do something like this:
Widget _getPage(int pos, user User) {
switch (pos) {
case 0:
return Home();
case 1:
return Search();
case 2:
return Account(user.profile); // Assuming profile is a member of user
default:
return Container();
}
}
Scaffold(
body: _getPage(_currentTab, user),
// ...
)