Flutter, How to use laravel API for flutter login - flutter

Im new to flutter and currently work as an intern in a small company, I'm trying to get API from laravel and try to login in flutter. Is there anyone can assist me to have a look on my code? I will write them below.
I'm trying to test it without token, but on online tutorial everyone is having token.
api.dart
import 'dart:convert';
import 'package:http/http.dart' as http;
import 'package:shared_preferences/shared_preferences.dart';
class Network{
final String _url = 'http://192.168.0.138:8000/api/';
var token;
_getToken() async {
SharedPreferences localStorage = await SharedPreferences.getInstance();
token = jsonDecode(localStorage.getString('token'))['token'];
}
authData(data, apiUrl) async {
var fullUrl = _url + apiUrl;
return await http.post(
fullUrl,
body: jsonEncode(data),
headers: _setHeaders()
);
}
getData(apiUrl) async {
var fullUrl = _url + apiUrl;
await _getToken();
return await http.get(
fullUrl,
headers: _setHeaders()
);
}
_setHeaders() => {
'Content-type' : 'application/json',
'Accept' : 'application/json',
'Authorization' : 'Bearer $token'
};
}
Login_Screen
import 'package:ezymember/screens/home_screen.dart';
import 'package:ezymember/screens/register_screen.dart';
import 'package:flutter/material.dart';
import 'dart:convert';
import 'package:ezymember/network_utils/api.dart';
import 'package:shared_preferences/shared_preferences.dart';
class LoginScreen extends StatefulWidget {
const LoginScreen({Key key}) : super(key: key);
#override
_LoginScreenState createState() => _LoginScreenState();
}
class _LoginScreenState extends State<LoginScreen> {
bool _isLoading = false;
final _formKey = GlobalKey<FormState>();
var member_email;
var member_password;
final _scaffoldKey = GlobalKey<ScaffoldState>();
_showMsg(msg) {
final snackBar = SnackBar(
content: Text(msg),
action: SnackBarAction(
label: 'Close',
onPressed: () {
// Some code to undo the change!
},
),
);
_scaffoldKey.currentState.showSnackBar(snackBar);
}
#override
Widget build(BuildContext context) {
return Scaffold(
key: _scaffoldKey,
body: SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Stack(
children: <Widget>[
Container(
padding: const EdgeInsets.fromLTRB(15.0, 110.0, 0.0, 0.0),
child: const Text('Hello',
style:
TextStyle(fontSize: 80.0, fontWeight: FontWeight.bold)),
),
Container(
padding: const EdgeInsets.fromLTRB(16.0, 175.0, 0.0, 0.0),
child: const Text('There',
style:
TextStyle(fontSize: 80.0, fontWeight: FontWeight.bold)),
),
Container(
padding: const EdgeInsets.fromLTRB(220.0, 175.0, 0.0, 0.0),
child: const Text('.',
style: TextStyle(
fontSize: 80.0,
fontWeight: FontWeight.bold,
color: Colors.blue)),
)
],
),
Container(
padding: const EdgeInsets.only(top: 35.0, left: 20.0, right: 20.0),
child: Form(
key: _formKey,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
TextFormField(
keyboardType: TextInputType.text,
decoration: const InputDecoration(
labelText: 'EMAIL',
labelStyle: TextStyle(
fontFamily: 'Montserrat',
fontWeight: FontWeight.bold,
color: Colors.grey),
focusedBorder: UnderlineInputBorder(
borderSide: BorderSide(color: Colors.blue)),
),
validator: (emailValue) {
if (emailValue.isEmpty) {
return 'Please enter email';
}
member_email = emailValue;
return null;
},
),
TextFormField(
keyboardType: TextInputType.text,
decoration: const InputDecoration(
labelText: 'PASSWORD',
labelStyle: TextStyle(
fontFamily: 'Montserrat',
fontWeight: FontWeight.bold,
color: Colors.grey),
focusedBorder: UnderlineInputBorder(
borderSide: BorderSide(color: Colors.blue)),
),
validator: (passwordValue) {
if (passwordValue.isEmpty) {
return 'Please Enter Password';
}
member_password = passwordValue;
return null;
},
),
Padding(
padding: const EdgeInsets.all(10.0),
child: FlatButton(
child: Padding(
padding: const EdgeInsets.only(
top: 8, bottom: 8, left: 10, right: 10),
child: Text(
_isLoading ? 'Proccessing...' : 'Login',
textDirection: TextDirection.ltr,
style: const TextStyle(
color: Colors.white,
fontSize: 20.0,
decoration: TextDecoration.none,
fontWeight: FontWeight.normal,
),
),
),
color: Colors.blue,
disabledColor: Colors.grey,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20.0)),
onPressed: () {
if (_formKey.currentState.validate()) {
_login();
}
},
),
),
],
),
),
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
const Text(
'New to EzyMember ?',
style: TextStyle(fontFamily: 'Montserrat'),
),
const SizedBox(width: 5.0),
InkWell(
onTap: () {
Navigator.push(context,
MaterialPageRoute(builder: (context) => RegisterPage()));
},
child: const Text(
'Register',
style: TextStyle(
color: Colors.blue,
fontFamily: 'Montserrat',
fontWeight: FontWeight.bold,
decoration: TextDecoration.underline),
),
),
],
),
],
),
),
);
}
void _login() async {
setState(() {
_isLoading = true;
});
var data = {'email': member_email, 'password': member_password};
var res = await Network().authData(data, '/login');
var body = json.decode(res.body);
if (body['success']) {
SharedPreferences localStorage = await SharedPreferences.getInstance();
localStorage.setString('token', json.encode(body['token']));
localStorage.setString('user', json.encode(body['user']));
Navigator.push(
context,
MaterialPageRoute(builder: (context) => const HomeScreen()),
);
} else {
_showMsg(body['message']);
}
setState(() {
_isLoading = false;
});
}
}

Related

Flutter - Quantity of all Products returns same value after OnClick

To keep things short:
I have multiple products, where you can increment and decrement their value(qnty) inside the cart and after Submitting, a receipt is generated based on the cart Items.
So the Problem is whenever I try to slide the submit, the qnty of the first product I added to cart is assigned to every product, Like
• Apple: 1
• Mango: 2
• Orange: 6
Above is how it should be like
• Apple: 6
• Mango: 6
• Orange: 6
This is the result I am getting, Note: The Result is from new to old
Secondary issue is that whenever I try to write any value inside the textfield and click submit, the value still doesn't get updated!
The Code consists of 2 files:
Parent File
import 'package:ambica_medico/component/result/productcart.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import 'package:flutter_email_sender/flutter_email_sender.dart';
import 'package:url_launcher/url_launcher.dart';
import 'package:whatsapp_unilink/whatsapp_unilink.dart';
import '../../component/buttons/c_button.dart';
import '../../constant.dart';
final FirebaseAuth auth = FirebaseAuth.instance;
Stream<QuerySnapshot> getData() => FirebaseFirestore.instance
.collection('Users')
.doc(auth.currentUser?.uid)
.collection('Carts')
.snapshots();
class Cart extends StatefulWidget {
const Cart({Key? key}) : super(key: key);
#override
State<Cart> createState() => _CartState();
}
class _CartState extends State<Cart> {
String _text = '';
callback(newAbc) {
pk = newAbc;
} //Step 5: Callback ready to be passed to the the Procart.
String? product;
String qnty = '';
String? mail;
String? name;
String? address;
String? dln;
String? gst;
late final _getData = getData();
DateTime now = DateTime.now();
Map<String, String> pk = {};
#override
Widget build(BuildContext context) {
return StreamBuilder<dynamic>(
stream: _getData,
builder: (context, snapshot) {
final tilesList = <Widget>[];
if (snapshot.hasData) {
snapshot.data.docs.forEach((value) {
qnty = value.data()['SIB'].toString();
pk = {value.id: qnty}; //Step4: A map which holds every product id and qnty
final productTile = Procart(
pname: value.data()['Product'],
subtitle: value.data()['MRP'],
keyo: value.id,
controller: qnty, sib: value.data()['OSIB'], tis: value.data()['TIS'], callback: callback, //Callback passed!
);
if (_text.isEmpty) {
tilesList.add(productTile);
} else {
if (value
.data()['Product']
.toUpperCase()
.contains(_text.toUpperCase())) {
tilesList.add(productTile);
}
}
// print(pk.values); //Returns 5,1
});
return SafeArea(
child: Scaffold(
resizeToAvoidBottomInset: false,
appBar: AppBar(
leading: Padding(
padding: const EdgeInsets.only(left: 20.0, top: 10),
child: IconButton(
icon: const Icon(
Icons.arrow_back_ios_new_rounded,
color: Colors.black,
size: 20,
),
onPressed: () {
Navigator.pop(context);
},
),
),
backgroundColor: const Color(0xFFf5f3f7),
elevation: 0,
),
body: GestureDetector(
onTap: () => FocusManager.instance.primaryFocus?.unfocus(),
child: Container(
decoration: kImageBackground.copyWith(),
height: MediaQuery.of(context).size.height,
child: Stack(children: [
Column(
children: [
SingleChildScrollView(
child: Padding(
padding: const EdgeInsets.only(
left: 24.0, right: 24.0, top: 40),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
mainAxisAlignment: MainAxisAlignment.start,
children: [
const Text(
'The Cart',
style: TextStyle(
fontSize: 40,
fontFamily: 'ProductSans',
fontWeight: FontWeight.bold,
color: Colors.black,
),
),
Padding(
padding:
const EdgeInsets.only(top: 50, bottom: 50),
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(20),
color: Colors.white,
boxShadow: const [
BoxShadow(
color: Color(0x261B1B1A),
blurRadius: 50.0,
spreadRadius: 0,
offset: Offset(0.0, 30.0),
),
],
),
height: 70,
child: Center(
child: TextField(
onChanged: (value) {
setState(() {
_text = value;
});
},
keyboardType: TextInputType.text,
decoration: kDecorS.copyWith(
hintText: 'Search Products',
),
style: const TextStyle(
fontFamily: 'ProductSans',
fontSize: 18,
fontWeight: FontWeight.w400,
color: Color(0xff0f1511),
),
),
),
),
),
],
),
),
),
SizedBox(
height: MediaQuery.of(context).size.height * 0.55,
child: ListView(
shrinkWrap: true,
physics: const BouncingScrollPhysics(),
children: tilesList,
),
),
],
),
Positioned(
bottom: 0,
child: SingleChildScrollView(
physics: const NeverScrollableScrollPhysics(),
child: Align(
alignment: Alignment.bottomCenter,
child: Container(
width: MediaQuery.of(context).size.width,
decoration: const BoxDecoration(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(42.0),
topRight: Radius.circular(42.0),
),
color: Colors.white,
),
child: Padding(
padding: const EdgeInsets.only(top: 20),
child: Column(
children: [
const Padding(
padding:
EdgeInsets.only(bottom: 10.0),
child: Center(
child: Text(
'Check and then click below to',
style: TextStyle(
fontSize: 14,
fontFamily: 'ProductSans',
fontWeight: FontWeight.bold,
color: Colors.black,
),
),
),
),
Cbutton(
text: 'Send Order',
onPressed: () async {
String message = "";
DateTime date = DateTime(
now.year, now.month, now.day);
await FirebaseFirestore.instance
.collection('Users')
.doc(auth.currentUser?.uid)
.get()
.then((value) => {
name = value.data()!['name'],
address =
value.data()!['address'],
dln = value.data()!['dln'],
gst = value.data()!['gst'],
});
await snapshot.data.docs
.forEach((value) async {
product = value.data()['Product'];
message += '- $product = ${pk.values} \n';
});
final Email email = Email(
body:
"From:- \n\nName: $name\n\nAddress: $address\n\nDrug License No:- $dln\n\nGST No:- $gst\n\nDate:- $date \n\nDear sir,\nPlease dispatch my following order earliest possible through\n $message \n\nThanks & Regards,\n$name",
subject: 'Order Detail',
recipients: ['calagency03#gmail.com'],
isHTML: false,
);
final link = WhatsAppUnilink(
phoneNumber: '+91 2313210000',
text:
"From:- \n\nName: $name\n\nAddress: $address\n\nDrug License No:- $dln\n\nGST No:- $gst\n\nDate:- $date \n\nDear sir,\nPlease dispatch my following order earliest possible through\n $message \n\nThanks & Regards,\n$name",
);
await FlutterEmailSender.send(email);
final url = Uri.parse('$link');
await launchUrl(url, mode: LaunchMode.externalApplication,);
},
icon: const Icon(
Icons.send_rounded,
color: Colors.black,
size: 20,
),
color: const Color(0xff0f1511),
),
],
),
),
),
),
),
)
]),
),
),
),
);
} else {
return const Center(
child: CircularProgressIndicator(),
);
}
});
}
}
The main logic of printing the receipt for a product is:
await snapshot.data.docs
.forEach((value) async {
product = value.data()['Product'];
message += '- $product = ${pk.values} \n';
});
Child File
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import 'package:flutter_slidable/flutter_slidable.dart';
class Procart extends StatefulWidget {
final String pname;
final String subtitle;
final String keyo; // Step1: Product id
final String sib;
final String tis;
final String controller; // Step2: Initial Value/ Qnty
final Function(Map) callback; // Step3: Callback to parents widget in which it passes updated qnty
const Procart(
{Key? key,
required this.pname,
required this.subtitle,
required this.keyo, required this.controller, required this.sib, required this.tis, required this.callback})
: super(key: key);
#override
State<Procart> createState() => _ProcartState();
}
class _ProcartState extends State<Procart> {
final FirebaseAuth auth = FirebaseAuth.instance;
late TextEditingController controller = TextEditingController(text: widget.controller);
Map<String, String> lk = {};
sub() {
setState(() {
controller.text =
(int.parse(controller.text) - 1).toString();
});
}
add() {
setState(() {
controller.text =
(int.parse(controller.text) + 1).toString();
});
}
// #override
// void didUpdateWidget(covariant Procart oldWidget) {
// // TODO: implement didUpdateWidget
// super.didUpdateWidget(oldWidget);
//
//
// }
#override
Widget build(BuildContext context) {
lk = { widget.keyo : controller.text }; // This map is used to store updated value
widget.callback(lk); // send updated value back to parent class but the value still remains 2,2,2 instead of 1,7,2
print(lk.values);
return GestureDetector(
onTap: () => FocusManager.instance.primaryFocus?.unfocus(),
child: Padding(
padding: const EdgeInsets.only(bottom: 10),
child: Slidable(
key: Key(widget.keyo),
endActionPane: ActionPane(motion: const ScrollMotion(), children: [
SlidableAction(
// An action can be bigger than the others.
onPressed: (value) {
FirebaseFirestore.instance
.collection('Users')
.doc(auth.currentUser?.uid)
.collection('Carts')
.doc(widget.keyo)
.delete();
},
backgroundColor: const Color(0xFFD16464),
foregroundColor: Colors.white,
icon: Icons.clear_rounded,
),
]),
child: Padding(
padding: const EdgeInsets.only(left: 28.0, right: 28.0),
child: Container(
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(10)
),
child: Padding(
padding: const EdgeInsets.all(12.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
SizedBox(
width: MediaQuery.of(context).size.width * 0.4,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
widget.pname,
style: const TextStyle(
fontFamily: 'Satoshi',
fontSize: 16,
fontWeight: FontWeight.bold,
color: Color(0xff0f1511),
),
),
Text(
'${widget.subtitle} | ${widget.sib} x ${widget.tis}',
style: const TextStyle(
fontFamily: 'Satoshi',
fontSize: 12,
fontWeight: FontWeight.normal,
color: Color(0xff0f1511),
),
),
],
),
),
Row(
children: [
CircleAvatar(
radius: 16,
backgroundColor: const Color(0xff1b1b1b),
child: IconButton(
iconSize: 13,
icon: const Icon(
Icons.remove,
color: Colors.white,
),
onPressed: () {
if (int.parse(controller.text) >
int.parse(widget.sib)) {
sub();
}
},
),
),
SizedBox(
width: 80,
child: TextFormField(
textAlign: TextAlign.center,
decoration: const InputDecoration(
border: InputBorder.none,
contentPadding: EdgeInsets.only(left: 6, right: 6),
),
controller: controller,
onEditingComplete: () {
controller;
},
keyboardType: TextInputType.number,
style: const TextStyle(
fontFamily: 'Satoshi',
fontSize: 16.0,
fontWeight: FontWeight.bold,
color: Color(0xff0f1511),
),
),
),
CircleAvatar(
radius: 16,
backgroundColor: const Color(0x33bababa),
child: IconButton(
iconSize: 13,
icon: const Icon(
Icons.add,
color: Color(0xff1b1b1b),
),
onPressed: () {
add();
},
),
),
],
),
]),
),
),
))),
);
}
}
For more info I have attached Screenshots below:
A Huge Thank you to anyone who helps me in solving this!
Well, I solved this issue by following the steps below:

How to make a simple admin page in flutter with a given email and password in flutter?

How can I add an admin page to the existing pages?
I just want one default admin to enter which will only display users from Firebase. I would like a specific email and password to be given which will allow access for that one admin.
I'm attaching the login page
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import 'startuppage.dart';
class MyLogin extends StatefulWidget {
const MyLogin({Key? key}) : super(key: key);
#override
State<MyLogin> createState() => _MyLoginState();
}
class _MyLoginState extends State<MyLogin> {
//editing controller
final TextEditingController emailController = TextEditingController();
final TextEditingController passwordController = TextEditingController();
int _success = 1 ;
late String _userEmail = "";
final user = FirebaseAuth.instance.currentUser;
Future SignIn() async {
await FirebaseAuth.instance.signInWithEmailAndPassword(
email: emailController.text.trim(),
password: passwordController.text.trim()
);
}
#override
Widget build(BuildContext context) {
return Container(
decoration: const BoxDecoration(
//color: Color(0xFFaac8ba),
gradient: LinearGradient
(begin: Alignment.bottomLeft,
end: Alignment.bottomRight,
colors: [
Color(0xFFde6262),
Color(0xFFffb88c)
]
),
),
child : Scaffold(
backgroundColor: Colors.transparent, //By default, in scaffold the bg color is white.
body: Container(
padding: const EdgeInsets.only(top: 130, left: 35, right: 0),
child: SingleChildScrollView(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text(
"Welcome Back\nTo Check-it.",
style: TextStyle(
color: Colors.black,
fontSize: 30,
fontFamily: 'Montserrat',
letterSpacing: 3,
fontWeight: FontWeight.bold,
),
),
const SizedBox(
height: 50.0,
),
TextField(
controller: emailController,
keyboardType: TextInputType.emailAddress,
decoration: const InputDecoration(
hintText: "Email",
prefixIcon: Icon(Icons.mail, color: Colors.black,)
),
),
const SizedBox(
height: 20.0,
),
TextField(
controller:passwordController,
obscureText: true,
keyboardType: TextInputType.visiblePassword,
decoration: const InputDecoration(
hintText: "Password",
prefixIcon: Icon(Icons.lock, color: Colors.black,)
),
),
const SizedBox(
height: 50.0,
),
ElevatedButton(
onPressed: () async{
// _signIn();
SignIn();
Navigator.push(
context,
MaterialPageRoute(builder: (context) => const Imageslider()),
);
},
style: ButtonStyle(
backgroundColor: MaterialStateProperty.all<Color>(Colors.black12),
),
child: const Text("Login",
style: TextStyle(
fontSize: 18,
color: Colors.black54),
),
),
const SizedBox(
height: 10.0,
),
Container(
alignment: Alignment.bottomCenter,
child: Text(
_success == 1
?''
: (
_success == 2
? 'Sign-in successful! '
: 'Sign-in failed!'),
style: const TextStyle(
color: Colors.white70,
)
),
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
TextButton(
onPressed: () {
Navigator.pushNamed(context,'signup');
},
child: const Text ('New User? Sign Up',
style : TextStyle(
decoration: TextDecoration.underline,
fontSize: 18,
color: Colors.black45,
),
)),
],
),
],
),
),
),
),
);
}
}
Sign Up Page Code :
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:flutter/material.dart';
import 'login.dart';
import 'startuppage.dart';
final FirebaseAuth _auth = FirebaseAuth.instance;
class Mysignup extends StatefulWidget {
const Mysignup({Key? key}) : super(key: key);
#override
State<Mysignup> createState() => _MysignupState();
}
class _MysignupState extends State<Mysignup> {
Future<FirebaseApp> _initializeFirebase() async {
FirebaseApp firebaseApp = await Firebase.initializeApp();
return firebaseApp;
}
//editing controller
final TextEditingController name = TextEditingController();
final TextEditingController emailController = TextEditingController();
final TextEditingController passwordController = TextEditingController();
late bool _success;
bool isLoading = false;
Future<User?> _register(String name, String email, String password) async{
FirebaseAuth _auth = FirebaseAuth.instance;
FirebaseFirestore _firestore = FirebaseFirestore.instance;
try {
UserCredential userCrendetial = await _auth.createUserWithEmailAndPassword(email: emailController.text, password: passwordController.text);
print("Account created Succesfull");
userCrendetial.user?.updateDisplayName(name);
await _firestore.collection('users').doc(_auth.currentUser?.uid).set({
"name": name,
"email": email,
"uid": _auth.currentUser?.uid,
});
return userCrendetial.user;
} catch (e) {
print(e);
return null;
}
}
#override
Widget build(BuildContext context) {
return Container(
decoration: const BoxDecoration(
gradient: LinearGradient
(colors: [
Color(0xFF02aab0),
Color(0xFF00cdac)
],
),
),
child : Scaffold(
backgroundColor: Colors.transparent, //By default, in scaffold the bg color is white.
body: Container(
padding: const EdgeInsets.only(top: 150, left: 35, right: 35),
child: SingleChildScrollView(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text(
"Let's Create Together.",
style: TextStyle(
color: Colors.black,
fontSize: 30,
letterSpacing: 3,
fontWeight: FontWeight.bold,
),
),
const SizedBox(
height: 40.0,
),
TextField(
controller:name,
keyboardType: TextInputType.name,
decoration: const InputDecoration(
hintText: "Name",
prefixIcon: Icon(Icons.account_circle_rounded, color: Colors.black,)
),
),
const SizedBox(
height: 20.0,
),
TextField(
controller:emailController,
keyboardType: TextInputType.emailAddress,
decoration: const InputDecoration(
hintText: "Email",
prefixIcon: Icon(Icons.mail, color: Colors.black,)
),
),
const SizedBox(
height: 20.0,
),
TextField(
controller:passwordController,
obscureText: true,
keyboardType: TextInputType.visiblePassword,
decoration: const InputDecoration(
hintText: "Password",
prefixIcon: Icon(Icons.lock, color: Colors.black,)
),
),
const SizedBox(
height: 80.0,
),
ElevatedButton(
onPressed: () async{
if (name.text.isNotEmpty &&
emailController.text.isNotEmpty &&
passwordController.text.isNotEmpty) {
setState(() {
isLoading = true;
});
_register(name.text, emailController.text, passwordController.text).then((user) {
if (user == null) {
setState(() {
isLoading = false;
});
Navigator.push(
context, MaterialPageRoute(builder: (_) => MyLogin()));
print("Account Created Sucessful");
} else {
print("Login Failed");
setState(() {
isLoading = false;
});
}
});
} else {
print("Please enter all the fields");
}
},
style: ButtonStyle(
backgroundColor: MaterialStateProperty.all<Color>(Colors.black12),
),
child: const Text("Sign Up",
style: TextStyle(
fontSize: 18,
fontWeight: FontWeight.bold,
color: Colors.black54),
),
),
],
),
),
),
),
);
}
}
I'm a beginner in FLutter. Please help. Thanks in advance!
You'll want to use StreamBuilder to respond to the FirebaseAuth.instance.authStateChanges() stream that is shown in the first snippet on getting the current user, then detect whether it is the admin user who signed in based on their UID, and then show them the admin page of your UI.
Something like:
child: StreamBuilder(
stream: FirebaseAuth.instance.authStateChanges(),
builder: (context, userSnapshot) {
if (userSnapshot.connectionState == ConnectionState.waiting) {
return CircularProgressIndicator();
}
if (userSnapshot.connectionState == ConnectionState.done) {
if (!userSnapshot.hasData) {
// TODO: return screen where they sign in
}
else if (userSnapshot.data!.uid == "uidOfYourAdminUser") {
// TODO: return admin screen
}else{
// TODO: return screen for regular signed in user
}
}
}
)

how to refresh page after send POST API in flutter

I have a POST API that when I send a request, I give the GET API request on the same screen to show the json data.
When I send information, after sending the information, the Get data is not displayed and must be logged out to display GET API data.
How can I refresh the page after sending the POST API data, so that the information is displayed after sending
POST API:
void ladderAsli() async {
if (_avgWeeklySales.text.isNotEmpty) {
print(token);
var response = await http.post(
Uri.parse("localhost/backend/api/v1/pellekan/main/add/"),
body: ({
"avgWeeklySales": _avgWeeklySales.text,
}),
headers: {
'Authorization': 'Bearer $token',
});
var body = jsonDecode(response.body);
if (response.statusCode == 200) {
SharedPreferences pref = await SharedPreferences.getInstance();
ScaffoldMessenger.of(context)
.showSnackBar(SnackBar(content: Text('${body['success']}')));
} else {
ScaffoldMessenger.of(context)
.showSnackBar(SnackBar(content: Text('${body['error']}')));
}
} else {
ScaffoldMessenger.of(context)
.showSnackBar(SnackBar(content: Text('error')));
}
}
and GET API:
Future getDataLadder() async {
print('bye');
String token = await getToken();
var response = await http.get(
Uri.parse('localhost/backend/api/v1/pellekan/main/active'),
headers: {
'Content-type': 'application/json',
'Accept': 'application/json',
'Authorization': 'Bearer $token',
});
print('Token : ${token}');
print('Response Body : ${response.body}');
if (response.statusCode == 400) {
var chieIN = jsonDecode(response.body);
print("be moshkel khordim hich dataei nist");
}
if (response.statusCode == 200) {
var chieIN = jsonDecode(response.body);
// print('Hosssssein ' +
// chieIN['pellekanInfo']['pellekanPublishStatus'].toString());
val = chieIN['pellekanInfo']['pellekanPublishStatus'].toString();
print('BODOBA : ${val}');
setState(() {
val = '0';
});
//setState(() {
// stringResponse = jsonDecode(response.body)['pellekan'];
// val!.add(chieIN['pellekanInfo']['pellekanPublishStatus'].toString());
stringResponse = [];
stringResponse.addAll(List<NardebanData>.from(json
.decode(response.body)['pellekan']
.map((x) => NardebanData.fromJson(x))));
print('String Response : ${stringResponse}');
// nardeban_data = (stringResponse as List<NardebanData>).map((d) => NardebanData.fromJson(d)).toList();
//});
} else {
print("error");
}
}
in the initState call getDataLadder()
Refreshpage
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:project/pattern_formatter.dart';
import 'package:project/screens/result-ladder.dart';
import 'package:http/http.dart' as http;
import 'package:shared_preferences/shared_preferences.dart';
List<NardebanData> nardeban_data = [];
List<NardebanData> stringResponse = [];
class Ladder extends StatefulWidget {
const Ladder({Key? key}) : super(key: key);
#override
_LadderState createState() => _LadderState();
}
Future<String> getToken() async {
final SharedPreferences prefs = await SharedPreferences.getInstance();
return prefs.getString('login')!;
}
class _LadderState extends State<Ladder> {
bool value = true;
String? val = "";
String token = "";
#override
void initState() {
super.initState();
getDataLadder();
getInfo();
}
void getInfo() async {
SharedPreferences pref = await SharedPreferences.getInstance();
setState(() {
token = pref.getString("login")!;
});
}
TextEditingController _avgWeeklySales = TextEditingController();
TextEditingController _doubleSellingPricePercent = TextEditingController();
TextEditingController _tripleSellingPricePercent = TextEditingController();
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
body: Directionality(
textDirection: TextDirection.rtl, child: gochgochApp()));
}
Future getDataLadder() async {
print('bye');
String token = await getToken();
var response = await http.get(
Uri.parse('localhost/backend/api/v1/pellekan/main/active'),
headers: {
'Content-type': 'application/json',
'Accept': 'application/json',
'Authorization': 'Bearer $token',
});
print('Token : ${token}');
print('Response Body : ${response.body}');
if (response.statusCode == 400) {
var chieIN = jsonDecode(response.body);
print("be moshkel khordim hich dataei nist");
}
if (response.statusCode == 200) {
var chieIN = jsonDecode(response.body);
// print('Hosssssein ' +
// chieIN['pellekanInfo']['pellekanPublishStatus'].toString());
val = chieIN['pellekanInfo']['pellekanPublishStatus'].toString();
print('BODOBA : ${val}');
setState(() {
val = '0';
});
//setState(() {
// stringResponse = jsonDecode(response.body)['pellekan'];
// val!.add(chieIN['pellekanInfo']['pellekanPublishStatus'].toString());
stringResponse = [];
stringResponse.addAll(List<NardebanData>.from(json
.decode(response.body)['pellekan']
.map((x) => NardebanData.fromJson(x))));
print('String Response : ${stringResponse}');
// nardeban_data = (stringResponse as List<NardebanData>).map((d) => NardebanData.fromJson(d)).toList();
//});
} else {
print("hooooooooooooooooooooooooo");
}
}
// Future asyncokeyeData() async {
// SharedPreferences pref = await SharedPreferences.getInstance();
// val = pref.getString('okeyeData');
// }
Widget gochgochApp() {
print('Valiable : ${val}');
if (val == '0') {
print(val);
// return Container(
// height: 200.0,
// child: Center(child: Text('شما در انتظار تایید نیست')),
// );
// return alertInForProcessLadder();
return getBody();
// return getBody();
}
// if (val == '2' || val == null) {
// return getForm();
// }
else {
return getForm();
}
}
Widget alertInForProcessLadder() {
return (SafeArea(
child: Padding(
padding: EdgeInsets.symmetric(horizontal: 30, vertical: 24),
child: SingleChildScrollView(
child: Container(
child: Center(
child: Text(
'شما یک پلکان اصلی در انتظار تایید ادمین دارید و نمی توانید پلکان دیگری ایجاد کنید')),
height: 200.0,
),
)),
));
}
Widget getForm() {
return (SafeArea(
child: Padding(
padding: EdgeInsets.symmetric(horizontal: 30, vertical: 24),
child: SingleChildScrollView(
child: Column(
children: [
SizedBox(
height: 9,
),
Text(
"فرم نردبان اصلی",
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 18,
color: Colors.blue,
fontWeight: FontWeight.bold,
),
),
SizedBox(
height: 10,
),
Container(
padding: EdgeInsets.all(28),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(12),
),
child: Column(
children: [
Text(
'مبلغ را به تومان وارد کنید',
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 13,
color: Colors.black54,
fontWeight: FontWeight.bold,
),
),
SizedBox(
height: 4,
),
TextField(
controller: _avgWeeklySales,
textAlign: TextAlign.center,
cursorColor: Colors.blue,
keyboardType: TextInputType.number,
inputFormatters: [ThousandsFormatter()],
decoration: InputDecoration(
hintStyle:
TextStyle(color: Colors.black26, fontSize: 13),
hintText: 'مثال : 1,000,000',
border: OutlineInputBorder(),
hintTextDirection: TextDirection.rtl,
contentPadding: EdgeInsets.all(8),
),
),
SizedBox(
height: 22,
),
Text(
'درصد تخفیف برای 20 عدد',
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 13,
color: Colors.black54,
fontWeight: FontWeight.bold,
),
),
SizedBox(
height: 4,
),
TextField(
controller: _doubleSellingPricePercent,
textAlign: TextAlign.center,
cursorColor: Colors.blue,
keyboardType: TextInputType.number,
inputFormatters: [ThousandsFormatter()],
decoration: InputDecoration(
hintStyle:
TextStyle(color: Colors.black26, fontSize: 13),
hintText: 'مثال : 20',
border: OutlineInputBorder(),
hintTextDirection: TextDirection.rtl,
contentPadding: EdgeInsets.all(8),
),
),
SizedBox(
height: 22,
),
Text(
'درصد تخفیف برای 30 عدد',
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 13,
color: Colors.black54,
fontWeight: FontWeight.bold,
),
),
SizedBox(
height: 4,
),
TextField(
controller: _tripleSellingPricePercent,
textAlign: TextAlign.center,
cursorColor: Colors.blue,
keyboardType: TextInputType.number,
inputFormatters: [ThousandsFormatter()],
decoration: InputDecoration(
hintStyle:
TextStyle(color: Colors.black26, fontSize: 13),
hintText: 'مثال : 30',
border: OutlineInputBorder(),
hintTextDirection: TextDirection.rtl,
contentPadding: EdgeInsets.all(8),
),
),
SizedBox(
height: 25,
),
SizedBox(
width: double.infinity,
child: ElevatedButton(
onPressed: () {
ladderAsli();
},
style: ButtonStyle(
shape: MaterialStateProperty.all<
RoundedRectangleBorder>(
RoundedRectangleBorder(
borderRadius: BorderRadius.circular(15.0),
),
),
foregroundColor:
MaterialStateProperty.all<Color>(Colors.white),
backgroundColor:
MaterialStateProperty.all<Color>(Colors.blue),
),
child: Padding(
child: Text(
'تایید',
style: TextStyle(
fontWeight: FontWeight.bold, fontSize: 21),
),
padding: EdgeInsets.all(15.0),
),
),
),
],
),
),
],
),
)),
));
}
Widget getBody() {
var size = MediaQuery.of(context).size;
return Container(
width: size.width,
height: size.height,
decoration: BoxDecoration(
borderRadius: BorderRadius.only(
bottomLeft: Radius.circular(10),
bottomRight: Radius.circular(10)),
color: Colors.white),
child: SingleChildScrollView(
child: Column(
children: [
SizedBox(
height: 10,
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Flexible(
child: Container(
height: 1,
decoration:
BoxDecoration(color: Colors.grey.withOpacity(0.2)),
),
),
SizedBox(
width: 10,
),
buildHeader(
text: 'جهت فعال سازی پله 30 عددی فیلد زیر را فعال کنید',
child: buildSwitch(),
),
SizedBox(
width: 10,
),
Flexible(
child: Container(
height: 1,
decoration:
BoxDecoration(color: Colors.grey.withOpacity(0.2)),
),
),
],
),
SizedBox(
height: 15,
),
Column(
children: List.generate(stringResponse.length, (index) {
NardebanData dataItem = stringResponse[index];
return Column(
children: [
Padding(
padding: const EdgeInsets.only(right: 5, left: 5),
child: Container(
decoration: new BoxDecoration(
image: new DecorationImage(
image: new AssetImage("assets/images/bg.png"),
fit: BoxFit.fill,
),
),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Container(
height: 90,
// width: (size.width - 20) * 0.68,
child: Row(
children: [
SizedBox(width: 20), // give it width
Container(
width: 60,
decoration: BoxDecoration(
color: Colors.blue,
border:
Border.all(color: Colors.blue),
borderRadius:
BorderRadius.circular(40.0)),
child: Padding(
padding: EdgeInsets.all(10.0),
child: Text(dataItem.name!,
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 12.5,
fontWeight: FontWeight.bold,
color: Colors.white)))),
SizedBox(
width: 10,
),
Container(
child: Column(
mainAxisAlignment:
MainAxisAlignment.center,
crossAxisAlignment:
CrossAxisAlignment.start,
children: [
Text(
dataItem.form ?? '' + '',
style: TextStyle(
fontSize: 14,
color: Colors.black54,
fontWeight: FontWeight.w400),
overflow: TextOverflow.ellipsis,
),
],
),
),
Container(
child: Column(
mainAxisAlignment:
MainAxisAlignment.center,
crossAxisAlignment:
CrossAxisAlignment.start,
children: [
Text(
' تا ' + dataItem.to!,
style: TextStyle(
fontSize: 14,
color: Colors.black54,
fontWeight: FontWeight.w400),
overflow: TextOverflow.ellipsis,
),
],
),
)
],
),
),
Container(
width: (size.width - 120) * 0.32,
child: Row(
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: [
Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
border: Border.all(color: Colors.blue)),
child: Padding(
padding: const EdgeInsets.only(
right: 10,
bottom: 4,
left: 10,
top: 4),
child: Row(
children: [
SizedBox(
width: 25,
height: 25,
child: TextField(
textAlign: TextAlign.center,
keyboardType:
TextInputType.number,
decoration: InputDecoration(
hintText: dataItem.percent!,
border: InputBorder.none,
contentPadding: EdgeInsets.only(
bottom: 8,
top: 3,
),
),
),
)
],
),
),
),
// Icon(
// Icons.notifications,
// size: 22,
// color: Colors.blue.withOpacity(0.7),
// )
],
),
)
],
),
)),
],
);
})),
],
),
),
);
}
Widget buildHeader({
required Widget child,
required String text,
}) =>
Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Text(
text,
style: TextStyle(fontSize: 14, fontWeight: FontWeight.bold),
),
const SizedBox(height: 3),
child,
],
);
Widget buildSwitch() => Transform.scale(
scale: 2,
child: Switch.adaptive(
activeColor: Colors.blueAccent,
activeTrackColor: Colors.blue.withOpacity(0.4),
// inactiveThumbColor: Colors.orange,
// inactiveTrackColor: Colors.black87,
splashRadius: 50,
value: value,
onChanged: (value) => setState(() => this.value = value),
),
);
void ladderAsli() async {
if (_avgWeeklySales.text.isNotEmpty) {
print(token);
var response = await http.post(
Uri.parse("localhost/backend/api/v1/pellekan/main/add/"),
body: ({
"avgWeeklySales": _avgWeeklySales.text,
"doubleSellingPricePercent": _doubleSellingPricePercent.text,
"tripleSellingPricePercent": _tripleSellingPricePercent.text,
}),
headers: {
'Authorization': 'Bearer $token',
});
var body = jsonDecode(response.body);
if (response.statusCode == 200) {
SharedPreferences pref = await SharedPreferences.getInstance();
ScaffoldMessenger.of(context)
.showSnackBar(SnackBar(content: Text('${body['success']}')));
} else {
ScaffoldMessenger.of(context)
.showSnackBar(SnackBar(content: Text('${body['error']}')));
}
} else {
ScaffoldMessenger.of(context)
.showSnackBar(SnackBar(content: Text('مبلغ کل را وارد کنید')));
}
}
}
this is json sample:
{
"pellekan": [
{
"name": "پله 1",
"form": null,
"to": "9999",
"percent": 1
},
{
"name": "پله 2",
"form": "9999",
"to": 10.74,
"percent": 2.89
},
{
]
}
Listview.builder widget used to propagate the change in ui
ListView.builder(
itemCount: datajson!.length,
itemBuilder: (context, index) {
return Text(datajson![index].toString(),
style: TextStyle(fontSize: 10));
})
Here i use sample post and getmethod with future delay like mimic the api wait and supply the data.
void MygetData() {
Future.delayed(Duration(seconds: 3), () {
setState(() {
isloading = false;
datajson;
});
});
}
void posts() {
Future.delayed(Duration(seconds: 3), () {
// other post request
datajson?.add({"name": "2"});
MygetData();
});
}
SampleCode dartpad live
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
runApp(MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return MaterialApp(
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({Key? key, required this.title}) : super(key: key);
final String title;
#override
State<MyHomePage> createState() => _MyHomePageState();
}
int myvalue = 0;
List<Map<String, dynamic>>? datajson = [];
class _MyHomePageState extends State<MyHomePage> {
int _counter = 0;
bool isloading = false;
#override
void initState() {
isloading = true;
Future.delayed(Duration(seconds: 3), () {
setState(() {
datajson?.add({"name": "1"});
isloading = false;
});
});
}
void MygetData() {
Future.delayed(Duration(seconds: 3), () {
setState(() {
isloading = false;
datajson;
});
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
body: Column(
// shrinkWrap: true,
children: [
Container(
height: 45,
child: ElevatedButton(
onPressed: () {
setState(() {
isloading = true;
});
posts();
},
child: Text(
"Post",
style: TextStyle(fontSize: 10),
)),
),
Expanded(
child: ListView.builder(
itemCount: datajson!.length,
itemBuilder: (context, index) {
return Text(datajson![index].toString(),
style: TextStyle(fontSize: 10));
}),
),
isloading
? Container(
height: 50,
width: 50,
child: CircularProgressIndicator(),
)
: Text("")
],
),
);
}
void posts() {
Future.delayed(Duration(seconds: 3), () {
// other post request
datajson?.add({"name": "2"});
MygetData();
});
}
}
i think best and easy way to solve this problem.
Navigator.push(context,MaterialPageRoute(builder: (context) =>yourclass()));
but you should fetch data in initstate like this.
void initState() { fetchYourItems(); super.initState(); };

NoSuchMethod Error: Method called on null

//in this code i am tring to use connectivity. Android recommended me to add some classes, //getters setter, I added them at the end of the code automatically
import 'package:firebase_auth/firebase_auth.dart';[enter image description here][1]
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'signup.dart';
import 'home.dart';
import 'dart:async';
import 'dart:developer' as developer;
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
class Login extends StatefulWidget {
const Login({Key? key}) : super(key: key);
#override
_LoginState createState() => _LoginState();
}
//loginstate
class _LoginState extends State<Login> {
ConnectivityResult? _connectionStatus = ConnectivityResult.none;
final Connectivity _connectivity = Connectivity();
late StreamSubscription<ConnectivityResult> _connectivitySubscription;
#override
void initState() {
super.initState();
initConnectivity();
_connectivitySubscription =
_connectivity.onConnectivityChanged.listen(_updateConnectionStatus);
}
#override
void dispose() {
_connectivitySubscription.cancel();
super.dispose();
}
// Platform messages are asynchronous, so we initialize in an async method.
Future<void> initConnectivity() async {
late ConnectivityResult result;
// Platform messages may fail, so we use a try/catch PlatformException.
try {
result = await _connectivity.checkConnectivity();
} on PlatformException catch (e) {
developer.log('Couldn\'t check connectivity status', error: e);
return;
}
// If the widget was removed from the tree while the asynchronous platform
// message was in flight, we want to discard the reply rather than calling
// setState to update our non-existent appearance.
if (!mounted) {
return Future.value(null);
}
return _updateConnectionStatus(result);
}
Future<void> _updateConnectionStatus(ConnectivityResult result) async {
setState(() {
_connectionStatus = result;
});
}
//Login function
static Future<User?> loiginUsingEmailPassword(
{required String email,
required String password,
required BuildContext context}) async {
FirebaseAuth auth = FirebaseAuth.instance;
User? user;
try {
UserCredential userCredential = await auth.signInWithEmailAndPassword(
email: email, password: password);
user = userCredential.user;
} on FirebaseAuthException catch (e) {
if (e.code == "user-not-found") {
print("No user found for that email");
}
}
return user;
}
#override
Widget build(BuildContext context) {
//create textfield controller
TextEditingController _emailController = TextEditingController();
TextEditingController _passwordController = TextEditingController();
return Scaffold(
resizeToAvoidBottomInset: false,
body: SingleChildScrollView(
child: Column(
children: <Widget>[
Container(
padding: EdgeInsets.fromLTRB(15.0, 110.0, 0.0, 0.0),
child: Text(
'Bon Appétit',
style: TextStyle(
fontFamily: 'Pacifico',
fontSize: 50.0,
),
),
),
//new container
Container(
padding: EdgeInsets.only(top: 35.0, left: 20.0, right: 20.0),
child: Column(
children: [
TextField(
controller: _emailController,
decoration: InputDecoration(
focusedBorder: UnderlineInputBorder(
borderSide: BorderSide(color: Color(0xFFcaa052)),
),
labelText: 'EMAIL',
labelStyle: TextStyle(
fontFamily: 'Alegreya Sans',
fontWeight: FontWeight.bold,
color: Color(0xFFcaa052),
),
),
),
SizedBox(
height: 20.0,
),
TextField(
controller: _passwordController,
decoration: InputDecoration(
focusedBorder: UnderlineInputBorder(
borderSide: BorderSide(color: Color(0xFFcaa052)),
),
labelText: 'PASSWORD',
labelStyle: TextStyle(
fontFamily: 'Alegreya Sans',
fontWeight: FontWeight.bold,
color: Color(0xFFcaa052),
),
),
obscureText: true,
),
SizedBox(
height: 5.0,
),
Container(
alignment: Alignment(1.0, 0.0),
padding: EdgeInsets.only(top: 15.0, left: 20.0),
child: InkWell(
child: Text(
'Forgot Password',
style: TextStyle(
color: Color(0xFF5E0B0B),
fontWeight: FontWeight.bold,
fontFamily: 'Alegreya Sans',
decoration: TextDecoration.underline,
),
),
),
),
SizedBox(
height: 40.0,
),
],
),
),
SizedBox(
height: 15.0,
),
Container(
height: 40.0,
width: 400.0,
child: Material(
borderRadius: BorderRadius.circular(20.0),
shadowColor: Color(0xFFffffb1),
color: Color(0xFFffd180),
elevation: 7.0,
child: InkWell(
onTap: () async {
User? user = await loiginUsingEmailPassword(
email: _emailController.text,
password: _passwordController.text,
context: context);
print(user);
if (user != null) {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => Home()),
);
}
},
child: Center(
child: Text(
'LOGIN',
style: TextStyle(
color: Colors.black,
fontWeight: FontWeight.bold,
fontFamily: 'Alegreya Sans',
),
),
),
),
),
),
Container(
child: Text('Connection Status: ${_connectionStatus.toString()}'),
),
SizedBox(
height: 15.0,
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'New member?',
style: TextStyle(fontFamily: 'Alegreya Sans'),
),
SizedBox(
width: 5.0,
),
InkWell(
onTap: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => Signup()),
);
},
child: Text(
'Sign up',
style: TextStyle(
color: Color(0xFF5E0B0B),
fontWeight: FontWeight.bold,
fontFamily: 'Alegreya Sans',
decoration: TextDecoration.underline,
),
),
),
],
),
],
),
),
);
}
}
//i think because of below code i got error
class ConnectivityResult {
static ConnectivityResult? none;
}
class Connectivity {
get onConnectivityChanged => null;
checkConnectivity() {}
}

When routing to another page I get "There are multiple heroes that share the same tag within a subtree"

I am trying to navigate from one screen to another with route. When I hit the button for the page to move to the route provided I get the error:
I/flutter ( 8790): Another exception was thrown: There are multiple heroes that share the same tag within a subtree.
Sharing with you the source code:
import 'dart:convert';
import 'dart:io';
import 'package:dio/dio.dart';
import 'package:flutter/material.dart';
import 'package:flutter_counter/flutter_counter.dart';
import 'package:gender_selection/gender_selection.dart';
import 'package:group_chats/addContactUI.dart';
import 'package:group_chats/addPhone.dart';
import 'package:group_chats/letGoUI.dart';
import 'package:http/http.dart' as http;
import 'package:image_picker/image_picker.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'Animation/FadeAnimation.dart';
import 'Model/insertUserModel.dart';
class AddProfileUI extends StatefulWidget {
final List<String> listFriends;
final String phone;
AddProfileUI(this.listFriends, this.phone);
#override
_AddProfileUIState createState() => _AddProfileUIState();
}
class _AddProfileUIState extends State<AddProfileUI> {
File _image;
final picker = ImagePicker();
final _formKey = GlobalKey<FormState>();
String name = "";
String city = "";
TextEditingController dobController = TextEditingController();
bool single = false;
Gender gender;
final _scaffoldKey = GlobalKey<ScaffoldState>();
int defaultValue = 18;
List<String> selectedContact;
SharedPreferences prefs;
bool _loading = true;
Future initPrefs() async {
prefs = await SharedPreferences.getInstance();
}
uploadImage(String userId) async {
try {
FormData formData = new FormData.fromMap({
"file":
await MultipartFile.fromFile(_image.path, filename: "$userId.jpg"),
});
var response = await Dio().post(
"https://us-central1-app-backend-fc090.cloudfunctions.net/webApi/api/v1/upload_profile/$userId",
data: formData);
if (response.statusCode == 200)
return response.data;
else
return null;
} catch (e) {
print(e.toString());
return null;
}
}
Future<InsertUserModel> insertData() async {
try {
for (int i = 0; i < selectedContact.length; i++) {
if (selectedContact[i][0] == "0") {
selectedContact[i] = selectedContact[i].replaceRange(0, 1, "+972");
}
}
var body = jsonEncode({
"gender": gender.index == 0 ? "male" : "female",
"city": city,
"last_login": {},
"friends": selectedContact ?? [],
"single": single,
"name": name,
"phone_number": widget.phone,
"age": defaultValue
});
final String apiUrl =
"https://us-central1-app-backend-fc090.cloudfunctions.net/webApi/api/v1/users/${AddPhoneUI.uid}";
final response = await http.post(apiUrl,
headers: {"content-type": "application/json"}, body: body);
if (response.statusCode == 200) {
final responseString = response.body;
return insertUserModelFromJson(responseString);
}
} catch (e) {
setState(() {
_loading = false;
});
}
}
getUserData() async {
try {
final String apiUrl =
"https://us-central1-app-backend-fc090.cloudfunctions.net/webApi/api/v1/users/";
final response = await http.get(apiUrl);
if (response.statusCode == 200) {
final responseString = response.body;
return insertUserModelFromJson(responseString);
}
} catch (e) {
setState(() {
_loading = false;
});
Scaffold.of(context).showSnackBar(SnackBar(
backgroundColor: Colors.red,
content: Text('Error: ${e.toString()}'),
duration: Duration(milliseconds: 2500),
));
}
}
Future<void> _selectStartingDate(BuildContext context) async {
DateTime selectedDate = DateTime.now();
final DateTime picked = await showDatePicker(
context: context,
initialDate: selectedDate,
firstDate: DateTime(1950),
lastDate: DateTime(
DateTime.now().year, DateTime.now().month, DateTime.now().day),
);
if (picked != null && picked != selectedDate)
setState(() {
selectedDate = picked;
dobController.text = selectedDate.year.toString() +
"-" +
selectedDate.month.toString() +
"-" +
selectedDate.day.toString();
});
}
Future getImage() async {
final pickedFile = await picker.getImage(source: ImageSource.gallery);
setState(() {
_image = File(pickedFile.path);
});
}
showPopUp(BuildContext context) {
showDialog(
context: context,
builder: (context) => AlertDialog(
shape:
OutlineInputBorder(borderRadius: BorderRadius.circular(14.0)),
content: Container(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
SizedBox(
height: 20.0,
),
Text(
"My Profile",
style: TextStyle(
fontSize: 27.0, fontWeight: FontWeight.w600),
),
SizedBox(
height: 30.0,
),
RichText(
text: TextSpan(
text: "Your friends will be able to\nsee ",
style: TextStyle(
color: Colors.black,
fontSize: 18.0,
),
children: <TextSpan>[
TextSpan(
text: 'only',
style: TextStyle(
color: Colors.blue,
fontWeight: FontWeight.w500)),
TextSpan(text: 'your picture and\name.'),
],
)),
SizedBox(
height: 10.0,
),
RichText(
text: TextSpan(
text: "Other fields are used for\n",
style: TextStyle(
color: Colors.black,
fontSize: 18.0,
),
children: <TextSpan>[
TextSpan(
text: 'research issues',
style: TextStyle(
color: Colors.blue,
fontWeight: FontWeight.w500)),
TextSpan(text: "only."),
],
)),
SizedBox(
height: 10.0,
),
RichText(
text: TextSpan(
text: "Please fill all the fields.",
style: TextStyle(
color: Colors.black,
fontSize: 18.0,
),
)),
SizedBox(
height: 80.0,
),
MaterialButton(
shape: OutlineInputBorder(
borderSide: BorderSide(width: 1.0)),
color: Colors.white38,
child: Padding(
padding: const EdgeInsets.symmetric(
vertical: 10.0, horizontal: 20.0),
child: Text(
"Ok, got it",
style: TextStyle(fontSize: 18.0),
),
),
onPressed: () {
Navigator.pop(context);
},
),
],
),
),
));
}
#override
void initState() {
super.initState();
selectedContact = widget.listFriends;
initPrefs();
}
#override
Widget build(BuildContext context) {
return Scaffold(
key: _scaffoldKey,
body: SafeArea(
child: SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Padding(
padding: const EdgeInsets.only(right: 10.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
IconButton(
icon: Icon(Icons.arrow_back),
onPressed: () {},
),
GestureDetector(
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => AddContactUI(),
)).then((value) {
setState(() {
selectedContact = value;
});
});
},
child: Column(
children: [
Icon(
Icons.supervisor_account,
size: 40.0,
),
Text("Add Friends"),
],
),
)
],
),
),
Container(
child: GestureDetector(
onTap: () async {
await getImage();
},
child: CircleAvatar(
radius: 60.0,
backgroundImage: _image != null
? Image.file(_image).image
: Image.asset("assets/empty.png").image,
backgroundColor: Colors.transparent,
),
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: FadeAnimation(
1.7,
Form(
key: _formKey,
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
color: Colors.white,
boxShadow: [
BoxShadow(
color: Color(0xff5E17EB).withOpacity(0.3),
blurRadius: 20,
offset: Offset(0, 10),
)
]),
child: Column(
children: <Widget>[
Container(
padding: EdgeInsets.all(10),
decoration: BoxDecoration(
border: Border(
bottom:
BorderSide(color: Colors.grey[200]))),
child: TextFormField(
textInputAction: TextInputAction.next,
onFieldSubmitted: (_) =>
FocusScope.of(context).nextFocus(),
onChanged: (val) {
setState(() {
name = val;
});
},
validator: (val) =>
val.isEmpty ? "Enter Name" : null,
decoration: InputDecoration(
border: InputBorder.none,
hintText: "Name",
hintStyle: TextStyle(color: Colors.grey)),
),
),
Container(
decoration: BoxDecoration(
border: Border(
bottom:
BorderSide(color: Colors.grey[200]))),
padding: EdgeInsets.all(10),
child: TextFormField(
textInputAction: TextInputAction.next,
keyboardType: TextInputType.text,
onChanged: (val) {
setState(() {
city = val;
});
},
validator: (val) {
if (val.isEmpty) return "Enter City";
// if (val.length < 6)
// return "Password should be at least 6 characters";
return null;
},
decoration: InputDecoration(
border: InputBorder.none,
hintText: "City",
hintStyle: TextStyle(color: Colors.grey)),
),
),
Container(
height: 140.0,
padding: EdgeInsets.all(10),
child: GenderSelection(
selectedGender: gender,
maleText: "", //default Male
femaleText: "", //default Female
linearGradient: LinearGradient(colors: [
Colors.indigo,
Colors.black
]), //List: [Colors.indigo, Colors.black]
selectedGenderIconBackgroundColor:
Colors.indigo, // default red
checkIconAlignment:
Alignment.centerRight, // default bottomRight
selectedGenderCheckIcon:
null, // default Icons.check
onChanged: (Gender gender) {
this.gender = gender;
print(this.gender);
},
equallyAligned: true,
animationDuration: Duration(milliseconds: 400),
isCircular: true, // default : true,
isSelectedGenderIconCircular: true,
opacityOfGradient: 0.6,
padding: const EdgeInsets.all(3),
size: 120, //default : 120
),
),
SizedBox(
height: 10.0,
),
Row(
children: [
Checkbox(
value: single,
onChanged: (value) {
setState(() {
single = !single;
});
},
),
Text(
"Are you Single?",
style: TextStyle(fontSize: 16.0),
)
],
),
Padding(
padding: const EdgeInsets.all(14.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Text(
"Age:",
style: TextStyle(fontSize: 18.0),
),
Counter(
initialValue: defaultValue,
buttonSize: 35.0,
textStyle: TextStyle(fontSize: 25.0),
minValue: 0,
color: Colors.black,
maxValue: 80,
step: 1,
decimalPlaces: 0,
onChanged: (value) {
// get the latest value from here
setState(() {
defaultValue = value;
});
},
),
],
),
),
],
),
),
),
),
),
SizedBox(
height: 20.0,
),
FadeAnimation(
1.9,
MaterialButton(
shape: OutlineInputBorder(borderSide: BorderSide(width: 1.0)),
color: Colors.black,
child: Padding(
padding: const EdgeInsets.symmetric(
vertical: 10.0, horizontal: 20.0),
child: Text(
"Next",
style: TextStyle(
fontSize: 18.0,
color: Colors.white,
),
),
),
onPressed: () async {
if (_formKey.currentState.validate()) {
InsertUserModel result = await insertData();
// var imageResult = await uploadImage(result.id);
print(result.data[0].id);
if (_image != null) {
await uploadImage(result.data[0].id);
}
setState(() {
_loading = false;
});
if (result != null) {
await prefs.setString("userID", result.data[0].id);
final snackBar = SnackBar(
content: Text(
result.message,
style: TextStyle(color: Colors.white),
),
backgroundColor: Colors.green,
duration: Duration(milliseconds: 2000),
);
_scaffoldKey.currentState.showSnackBar(snackBar);
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => LetGoUI(result.data[0].id),
));
} else {
final snackBar = SnackBar(
content: Text(
"Here is some error, please try again later!",
style: TextStyle(color: Colors.white),
),
backgroundColor: Colors.red,
duration: Duration(milliseconds: 2000),
);
_scaffoldKey.currentState.showSnackBar(snackBar);
}
}
},
),
)
],
),
),
),
);
}
}
I really don't understand what is the problem because I'm not using any Heros and not have double FloatingActionButton.
How do I solve this?
Thanks
There might be problem with showing snackbar while navigating. you should remove that problem by calling following method before navigating.
void removeSnackBarCallsBeforeNavigation() {
ScaffoldMessenger.of(context).removeCurrentSnackBar();
}