LogIn screen skipped on flutter - user-interface

Currently I am designing my UI for the login screen and Firebase authentication is already in effect as I can see the username on the firebase console, however I try to edit my UI for the login screen, but the login screen is skipped and is continuously logged in, so I cannot see the changes I am making for the UI of my login screen, here is my code:
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:google_sign_in/google_sign_in.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'home.dart';
class Login extends StatefulWidget {
#override
_LoginState createState() => _LoginState();
}
class _LoginState extends State<Login> {
final GoogleSignIn googleSignIn = new GoogleSignIn();
final FirebaseAuth firebaseAuth = FirebaseAuth.instance;
SharedPreferences preferences;
bool loading = false;
bool isLogedin = false;
#override
void initState() {
super.initState();
isSignedIn();
}
void isSignedIn() async {
setState(() {
loading = true;
});
preferences = await SharedPreferences.getInstance();
isLogedin = await googleSignIn.isSignedIn();
if (isLogedin) {
Navigator.pushReplacement(
context, MaterialPageRoute(builder: (context) => HomePage()));
}
setState(() {
loading = false;
});
}
Future handleSignIn() async {
preferences = await SharedPreferences.getInstance();
setState(() {
loading = true;
});
GoogleSignInAccount googleUser = await googleSignIn.signIn();
GoogleSignInAuthentication googleSignInAuthentication =
await googleUser.authentication;
AuthCredential credential = GoogleAuthProvider.getCredential(
idToken: googleSignInAuthentication.idToken,
accessToken: googleSignInAuthentication.accessToken);
FirebaseUser firebaseUser =
(await firebaseAuth.signInWithCredential(credential)).user;
if (firebaseUser != null) {
final QuerySnapshot result = await Firestore.instance
.collection("users")
.where("id", isEqualTo: firebaseUser.uid)
.getDocuments();
final List<DocumentSnapshot> documents = result.documents;
if (documents.length == 0) {
//insert the user to our collection
Firestore.instance
.collection("users")
.document(firebaseUser.uid)
.setData({
"id": firebaseUser.uid,
"username": firebaseUser.displayName,
"profilePicture": firebaseUser.photoUrl
});
await preferences.setString("id", firebaseUser.uid);
await preferences.setString("username", firebaseUser.displayName);
await preferences.setString("photUrl", firebaseUser.displayName);
} else {
await preferences.setString("id", documents[0]['id']);
await preferences.setString("username", documents[0]['username']);
await preferences.setString("photoUrl", documents[0]['photoUrl']);
}
Fluttertoast.showToast(msg: "Login was successful");
setState(() {
loading = false;
});
Navigator.pushReplacement(
context, MaterialPageRoute(builder: (context) => HomePage()));
} else {
Fluttertoast.showToast(msg: "Login failed :(");
}
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Colors.white,
centerTitle: true,
title: new Text(
"Login",
style: TextStyle(color: Colors.red.shade900),
),
elevation: 0.1,
),
body: Stack(children: <Widget>[
Visibility(
visible: loading ?? true,
child: Center(
child: Container(
alignment: Alignment.center,
color: Colors.white.withOpacity(0.9),
child: CircularProgressIndicator(
valueColor: AlwaysStoppedAnimation<Color>(Colors.red),
))))
,
]),
bottomNavigationBar: Container(
child: Padding(
padding: const EdgeInsets.only(left:12.0, right: 12, top: 12, bottom: 12),
child: FlatButton(
color: Colors.red.shade900,
onPressed: () {
handleSignIn();
},
child: Text(
'Sign in/ Sign up with Google',
style: TextStyle(color: Colors.white),
)),
),
),
);
}
}
This is my code for the UI of login, however I cannot see the edits I am making on this on my emulator, as the login screen just skips (actually it appears for like 0.5 seconds and goes directly to the homepage). Could someone help me out?

You are navigating the logged-in user to the home page.
void isSignedIn() async {
setState(() {
loading = true;
});
preferences = await SharedPreferences.getInstance();
isLogedin = await googleSignIn.isSignedIn();
if (isLogedin) {
Navigator.pushReplacement(
context, MaterialPageRoute(builder: (context) => HomePage()));
}
setState(() {
loading = false;
});
}
Either you can implement Logout in the app or just comment out the auto logged in part until your testing finish.

Related

Flutter Deleting a record through the API

I am using a Laravel Api and a Flutter app as the client. This is a basic CRUD app and i was able to update the records through the API but when it comes to deleting a record, an exception is thrown and i am unable to findout the issue.
Laravel 8 App looks like this
routes\api.php
Route::apiResource('categories', \App\Http\Controllers\Api\CategoryController::class);
app\Http\Controllers\Api\CategoryController.php
public function destroy(Category $category)
{
$category->delete();
return response()->noContent();
}
Flutter App looks like this
lib\screens\categories.dart
import 'package:flutter/material.dart';
import 'package:demo_app/models/category.dart';
import 'package:demo_app/widgets/category_edit.dart';
import 'package:demo_app/providers/category_provider.dart';
import 'package:provider/provider.dart';
// import 'package:http/http.dart' as http;
class Categories extends StatefulWidget {
const Categories({super.key});
#override
CategoriesState createState() => CategoriesState();
}
class CategoriesState extends State<Categories> {
#override
Widget build(BuildContext context) {
final provider = Provider.of<CategoryProvider>(context);
List<Category> categories = provider.categories;
return Scaffold(
appBar: AppBar(
title: const Text('Categories'),
),
body: ListView.builder(
itemCount: categories.length,
itemBuilder: (context, index) {
Category category = categories[index];
return ListTile(
title: Text(category.name),
trailing:
Row(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
IconButton(
icon: const Icon(Icons.edit),
onPressed: () {
showModalBottomSheet(
isScrollControlled: true,
context: context,
builder: (context) {
return CategoryEdit(category, provider.updateCategory);
});
},
),
IconButton(
icon: const Icon(Icons.delete),
onPressed: () => showDialog(
context: context,
builder: (context) {
return AlertDialog(
title: const Text('confirmation'),
content: const Text('Are you sure you want to delete?'),
actions: [
TextButton(
onPressed: () => deleteCategory(provider.deleteCategory, category),
child: const Text('Confirm')
),
TextButton(
onPressed: () => Navigator.pop(context),
child: const Text('Cancel')
),
]
);
}
),
),
],
),
);
},
)
);
}
Future deleteCategory(Function callback, Category category) async{
await callback(category);
if (!mounted) return;
Navigator.pop(context);
}
}
lib\services\api.dart
// import 'dart:async';
import 'dart:convert';
import 'dart:io';
import 'package:demo_app/models/category.dart';
// import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
class ApiService{
ApiService();
final String baseUrl = 'http://flutter-api.test/api/';
Future<List<Category>> fetchCategories() async {
http.Response response =
await http.get(Uri.parse('${baseUrl}categories'));
List categories = jsonDecode(response.body);
return categories.map((category) => Category.fromJson(category)).toList();
}
Future <Category> updateCategory(Category category) async {
// String uri = '${baseUrl}categories/$category.id';
String uri = '${baseUrl}categories/${category.id}';
http.Response response = await http.put(Uri.parse(uri),
headers: {
HttpHeaders.contentTypeHeader: 'application/json',
HttpHeaders.acceptHeader: 'application/json',
},
body: jsonEncode({'name': category.name}));
if(response.statusCode != 200){
throw Exception('Error happened on update');
}
return Category.fromJson(jsonDecode(response.body));
}
Future<void> deleteCategory(id) async {
String uri = '${baseUrl}categories/$id';
http.Response response = await http.delete(Uri.parse(uri));
if(response.statusCode != 204){
throw Exception('Error happened on delete');
}
}
}
lib\providers\category_provider.dart
// import 'dart:io';
import 'package:demo_app/models/category.dart';
import 'package:flutter/material.dart';
import 'package:demo_app/services/api.dart';
class CategoryEdit extends StatefulWidget {
final Category category;
final Function categoryCallback;
const CategoryEdit(this.category, this.categoryCallback, {Key? key}) : super(key: key);
#override
CategoryEditState createState() => CategoryEditState();
}
class CategoryEditState extends State<CategoryEdit> {
final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
final categoryNameController = TextEditingController();
ApiService apiService = ApiService();
String errorMessage = '';
#override
void initState(){
categoryNameController.text = widget.category.name;
super.initState();
}
#override
Widget build(BuildContext context){
return Padding(
padding: const EdgeInsets.all(8.0),
child: Form(
key: _formKey,
child: Column(children: <Widget>[
TextFormField(
onChanged: (text) => setState(() => errorMessage = ''),
controller: categoryNameController,
validator: (String? value) {
if (value!.isEmpty) {
return 'Enter category name';
}
return null;
},
decoration: const InputDecoration(
border: OutlineInputBorder(),
labelText: 'Category Name',
),
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
ElevatedButton(
child: const Text('Save'),
onPressed: () => saveCategory(context),
),
ElevatedButton(
style: ElevatedButton.styleFrom(
backgroundColor: Colors.red
),
child: const Text('Cancel'),
onPressed: () => Navigator.pop(context),
),
],
),
Text(errorMessage, style: const TextStyle(color: Colors.red),)
]
)
)
);
}
Future saveCategory(BuildContext context) async {
final form = _formKey.currentState;
if(!form!.validate())
{
return;
}
widget.category.name = categoryNameController.text;
await widget.categoryCallback(widget.category);
if (!mounted) return;
Navigator.pop(context);
}
}
This is the exception i get
flutter: Exception: Error happened on delete
It returns the Error Code 500 and i was able to sort the error from the Server side

MissingPluginException(No implementation found for method login on channel app.meedu/flutter_facebook_auth)

i got this error but not solve.i follow the step properly
this is code of my login page
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import 'package:flutter_facebook_auth/flutter_facebook_auth.dart';
import 'package:google_sign_in/google_sign_in.dart';
import 'package:provider/provider.dart';
class loginpage extends StatefulWidget {
const loginpage({Key? key}) : super(key: key);
#override
State<loginpage> createState() => _loginpageState();
}
enum LoginType { facebook, google, apple }
class _loginpageState extends State<loginpage> {
FirebaseAuth _auth = FirebaseAuth.instance;
bool _fetching = true;
User? get _currentUser => _auth.currentUser;
#override
void initState() {
super.initState();
_checkLogin();
}
Future<void> _checkLogin() async {
await Future.delayed(Duration(seconds: 1));
_fetching = false;
setState(() {});
}
void _login(LoginType type) async {
setState(() {
_fetching = true;
});
OAuthCredential? credential;
if (type == LoginType.facebook) {
credential = (await _loginWithFacebook()) as OAuthCredential;
} else if (type == LoginType.google) {
credential = (await _loginWithGoogle()) as OAuthCredential;
}
if (credential != null) {
await _auth.signInWithCredential(credential);
}
setState(() {
_fetching = false;
});
}
Future<OAuthCredential?> _loginWithFacebook() async {
final AccessToken accessToken = (await FacebookAuth.instance.login()) as AccessToken;
print(accessToken);
return FacebookAuthProvider.credential(
accessToken.token,
);
}
Future<OAuthCredential?> _loginWithGoogle() async {
try {
final GoogleSignInAccount? account = await GoogleSignIn(scopes: ['email']).signIn();
if (account != null) {
// Obtain the auth details from the request
final GoogleSignInAuthentication googleAuth = await account.authentication;
return GoogleAuthProvider.credential(
accessToken: googleAuth.accessToken,
idToken: googleAuth.idToken,
);
}
return null;
} catch (e) {
print(e);
return null;
}
}
Future<void> _logOut() async {
final List<UserInfo> data = _currentUser!.providerData;
String providerId = "firebase";
for (final item in data) {
if (item.providerId != "firebase") {
providerId = item.providerId;
break;
}
}
await _auth.signOut();
setState(() {});
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: Container(
width: double.infinity,
height: double.infinity,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
if (!_fetching && _currentUser == null)
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
TextButton(
onPressed: () => _login(LoginType.facebook),
child: Text("FACEBOOK"),
),
SizedBox(width: 10),
TextButton (
onPressed: () => _login(LoginType.google),
child: Text("GOOGLE"),
),
],
),
if (_fetching) CircularProgressIndicator(),
if (_currentUser != null) ...[
Text("HI ...."),
Text(_currentUser!.displayName ??" "),
SizedBox(height: 20),
TextButton(
onPressed: _logOut,
child: Text("LOG OUT"),
),
]
],
),
),
),
);
}
}
how to solve this? i follow all instruction properly.

Hero animation with gallery flicker Flutter

I'm trying to create a basic Hero animation between a gallery grid view page (using photo manager plugin) and a detail page. When the hero animation is done both back and forward, the picture is flickering .
Here is the example I've made :
The full code runnable :
import 'dart:io';
import 'dart:typed_data';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:photo_manager/photo_manager.dart';
void main() {
runApp(const TestApp());
}
class TestApp extends StatefulWidget {
const TestApp({Key? key}) : super(key: key);
#override
State<TestApp> createState() => _TestAppState();
}
class _TestAppState extends State<TestApp> {
final List<AssetEntity> assetsList = [];
bool granted = false;
void loadAssets() async {
granted = await PhotoManager.requestPermission();
if (granted) {
FilterOptionGroup option = FilterOptionGroup()
..addOrderOption(const OrderOption(
type: OrderOptionType.createDate,
asc: false,
));
final albums = await PhotoManager.getAssetPathList(filterOption: option, type: RequestType.image);
print("albums : $albums");
if (albums.isNotEmpty) {
var alb = albums.where((element) {
return element.name == 'Test';
});
var album = alb.first;
// Now that we got the album, fetch all the assets it contains
List<AssetEntity> currentList =
await album.getAssetListRange(start: 0, end: 200);
// Update the state and notify UI
assetsList.clear();
assetsList.addAll(currentList);
}
setState(() {});
}
}
#override
void initState() {
loadAssets();
super.initState();
}
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: granted
? _gridView()
: Center(
child: Container(
color: Colors.blue,
width: 200,
height: 200,
child: TextButton(
onPressed: () async {
granted = await PhotoManager.requestPermission();
setState(() {});
},
child: const Text(
"Ask permission",
style: TextStyle(color: Colors.white),
),
)),
)),
);
}
Widget _gridView() {
return GridView.builder(
itemCount: assetsList.length,
gridDelegate:
const SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 3),
itemBuilder: (context, index) {
return Hero(
createRectTween: (Rect? begin, Rect? end) {
RectTween _rectTween = RectTween(begin: begin, end: end);
return _rectTween;
},
tag: assetsList[index].id,
child: GalleryThumbnail(
asset: assetsList[index],
onTap: (bytes) {
Navigator.push(context, MaterialPageRoute(builder: (context) {
return DetailsPage(asset: assetsList[index], bytes: bytes);
}));
},
));
});
}
}
class GalleryThumbnail extends StatelessWidget {
final AssetEntity asset;
final ValueChanged<Uint8List> onTap;
const GalleryThumbnail({Key? key, required this.asset, required this.onTap})
: super(key: key);
#override
Widget build(BuildContext context) {
return FutureBuilder<Uint8List?>(
future: Platform.isIOS
? asset.thumbDataWithOption(
ThumbOption.ios(
width: 500,
height: 500,
deliveryMode: DeliveryMode.opportunistic,
resizeMode: ResizeMode.fast,
resizeContentMode: ResizeContentMode.fit,
quality: 100
// resizeContentMode: ResizeContentMode.fill,
),
)
: asset.thumbDataWithSize(250, 250),
builder: (_, snapshot) {
final bytes = snapshot.data;
if (snapshot.hasError) {
return Container();
}
// If we have no data
if (bytes == null) return Container();
// If there's data, display it as an image
return GestureDetector(
onTap: () {
onTap(bytes);
},
child: Image.memory(bytes, fit: BoxFit.cover,gaplessPlayback: true,));
},
);
}
}
class DetailsPage extends StatefulWidget {
final AssetEntity asset;
final Uint8List bytes;
const DetailsPage({Key? key, required this.asset, required this.bytes})
: super(key: key);
#override
_DetailsPageState createState() => _DetailsPageState();
}
class _DetailsPageState extends State<DetailsPage> {
late ImageProvider _imageProvider;
Future<void> loadFile() async {
try {
File? file = await widget.asset.file;
if (file == null) return;
_imageProvider = Image.file(file).image;
setState(() {});
} catch (e) {
print("error to load file : " + e.toString());
}
}
#override
void initState() {
_imageProvider = Image.memory(widget.bytes).image;
loadFile();
super.initState();
}
#override
Widget build(BuildContext context) {
double ratio = widget.asset.height / widget.asset.width;
return Scaffold(
body: Stack(
children: [
Hero(
createRectTween: (Rect? begin, Rect? end) {
RectTween _rectTween = RectTween(begin: begin, end: end);
return _rectTween;
},
tag: widget.asset.id,
child: Center(
child: Image(image: _imageProvider,
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height*ratio,
gaplessPlayback: true),
),
),
const SafeArea(
child: Padding(
padding: EdgeInsets.all(8.0),
child: BackButton(),
)),
],
),
);
}
}
I've implemented hero animation somewhere else in my project and I'm not getting this behavior where as here I do.
Why this is happening and how to correct this ?
Add
transitionOnUserGestures: true,
to Hero() widget in current & next page
This happens because the Hero of the image thumbail wraps the FutureBuilder, and then the future triggers again during the animation, wraps the Image instead of the FutureBuilder.

Load image from sharedPreferences to pdf in Flutter

I'm need to load a image from sharedPreferences to a pdf document.
The image loads normally when in normal use, but i don't know how to make it load in the pdf.
When I try to load it like a normal image I get "Unhandled Exception: type 'Image' is not a subtype of type 'PdfImage'"
This is how I use it normally.
import 'package:flutter/material.dart';
import 'package:flutter_settings_screens/flutter_settings_screens.dart';
import 'package:image_picker/image_picker.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:MyApp/SharedPrefUtility.dart';
Future<void> initSettings() async {
await Settings.init(
cacheProvider: SharePreferenceCache(),
);
}
class ProfilePage extends StatefulWidget {
#override
_ProfilePageState createState() => _ProfilePageState();
}
class _ProfilePageState extends State<ProfilePage> {
Image logo;
pickImage(ImageSource source) async {
final _image = await ImagePicker.pickImage(source: ImageSource.gallery);
if (_image != null) {
setState(() {
logo = Image.file(_image);
});
ImageSharedPrefs.saveImageToPrefs(
ImageSharedPrefs.base64String(_image.readAsBytesSync()));
} else {
print('Error picking image!');
}
}
loadImageFromPrefs() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
final imageKeyValue = prefs.getString(IMAGE_KEY);
if (imageKeyValue != null) {
final imageString = await ImageSharedPrefs.loadImageFromPrefs();
setState(() {
logo = ImageSharedPrefs.imageFrom64BaseString(imageString);
});
}
}
#override
void initState() {
super.initState();
loadImageFromPrefs();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Colors.red,
title: Text('Profile Settings'),
),
body: Center(
child: ListView(
children: [
Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
ClipRect(
child: Container(
width: 300,
height: 300,
child: logo == null ? Text('No image selected.') : logo,
),
),
RaisedButton(
onPressed: () {
pickImage(ImageSource.gallery);
},
child: Text('Pick Company Logo'),
),
],
),
],
),
),
);
}
}
With SharedPrefUtility.dart
import 'dart:convert';
import 'dart:typed_data';
import 'package:flutter/widgets.dart';
import 'package:shared_preferences/shared_preferences.dart';
const IMAGE_KEY = 'IMAGE_KEY';
class ImageSharedPrefs {
static Future<bool> saveImageToPrefs(String value) async {
SharedPreferences prefs = await SharedPreferences.getInstance();
return await prefs.setString(IMAGE_KEY, value);
}
static Future<String> loadImageFromPrefs() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
return prefs.getString(IMAGE_KEY);
}
static String base64String(Uint8List data) {
return base64Encode(data);
}
static imageFrom64BaseString(String base64String) {
return Image.memory(
base64Decode(base64String),
fit: BoxFit.contain,
);
}
}
Any Suggestions would be great.
davey06 gave the answer on gitHub
final imageString = await ImageSharedPrefs.loadImageFromPrefs();
// Create a PDF document.
final document = pw.Document();
// Add page to the PDF
document.addPage(pw.Page(build: (context) {
return pw.Center(
child: pw.Image(
PdfImage.file(document.document, bytes: base64Decode(imageString)),
),
);
}));
// Return the PDF file content
return document.save();
https://github.com/DavBfr/dart_pdf/issues/477
"Unhandled Exception: type 'Image' is not a subtype of type 'PdfImage'" - it says you need to convert Image to PdfImage
import 'package:pdf/pdf.dart';
import 'package:pdf/widgets.dart ' as pw;
pdf = pw.Document();
PdfImage pdfImage = PdfImage.fromImage(pdf.document, image: logo);
pdf.addPage(
pw.Page(
pageFormat: PdfPageFormat.a4,
build: (context) {
return pw.Image(arcPdfImage, fit: pw.BoxFit.contain);
},
),
);
I'm using images taken from my assets to create PDF in this way:
PdfImage _logo = PdfImage.file(
doc.document,
bytes: (await rootBundle.load('assets/client-logo.png')).buffer.asUint8List(),
);
//later, during widget tree creation
pw.Image(_logo, width: 180);
It's not exactly what you're doing, but I think it's close enough. The PdfImage class can take as input any Uint8List for the bytes argument, so you should be able to use the same input you're using for the base64String method you defined for ImageSharedPrefs

How can I login on Flutter app with Laravel basic authenticaiton using email and password

After creating a new Laravel project, what I did was only making authentication using php artisan make:auth. I needed to get CSRF token to log in on the Flutter app, so I simple commented out CSRF token in the middleware.
The error I am getting is 302 which is redirection error. I was redirected to '/home'. So, I just simply returned 'User data' when successfully logged in, but I am still getting the same error. There is not enough documentation about Flutter of how to authenticate using email and password if i have web service already deployed on the web hosting company.
If I installed basic authentication on Laravel, how can I authenticate on Flutter? I don't need CSRF token for now for testing purposes.
flutter login code
import 'dart:async';
import 'dart:convert';
import 'dart:io';
import 'package:embedded_mobile/screens/home.dart';
import 'package:dio/dio.dart';
import 'package:flutter/material.dart';
import 'package:embedded_mobile/models/user.dart';
var routes = <String, WidgetBuilder>{
"/home": (BuildContext context) => HomeScreen(),
"/login": (BuildContext context) => LoginWithRestfulApi(),
};
class LoginWithRestfulApi extends StatefulWidget {
#override
_LoginWithRestfulApiState createState() => _LoginWithRestfulApiState();
}
class _LoginWithRestfulApiState extends State<LoginWithRestfulApi>
with TickerProviderStateMixin {
static var uri = "http://blackboardembedded.dx.am";
static BaseOptions options = BaseOptions(
baseUrl: uri,
responseType: ResponseType.plain,
connectTimeout: 30000,
receiveTimeout: 30000,
followRedirects: false,
validateStatus: (code) {
return code < 500;
});
static Dio dio = Dio(options);
GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();
TextEditingController _emailController = TextEditingController();
TextEditingController _passwordController = TextEditingController();
bool _isLoading = false;
Future<bool> _onBackPressed() {}
Future<dynamic> _loginUser(String email, String password) async {
try {
Options options = Options(
contentType: ContentType.parse('application/json'),
);
Response response = await dio.post('/login',
data: {"email": email, "password": password}, options: options);
if (response.statusCode == 200 ||
response.statusCode == 201 ) {
var responseJson = json.decode(response.data);
return responseJson;
} else if (response.statusCode == 401) {
throw Exception("Incorrect Email/Password");
} else
throw Exception('Authentication Error');
} on DioError catch (exception) {
if (exception == null ||
exception.toString().contains('SocketException')) {
throw Exception("Network Error");
} else if (exception.type == DioErrorType.RECEIVE_TIMEOUT ||
exception.type == DioErrorType.CONNECT_TIMEOUT) {
throw Exception(
"Could'nt connect, please ensure you have a stable network.");
} else {
return null;
}
}
}
#override
Widget build(BuildContext context) {
return Scaffold(
key: _scaffoldKey,
appBar: AppBar(
leading: new IconButton(
icon: new Icon(Icons.arrow_back, color: Colors.black),
onPressed: () => Navigator.of(context).pushNamed('/login'),
),
title: Text("Send Location")),
body: Center(
child: Container(
child: _isLoading
? CircularProgressIndicator()
: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Padding(
padding: const EdgeInsets.all(20.0),
child: TextField(
controller: _emailController,
decoration: InputDecoration(
hintText: 'Email',
),
),
),
Padding(
padding: const EdgeInsets.all(20.0),
child: TextField(
controller: _passwordController,
decoration: InputDecoration(
hintText: 'Password',
),
),
),
new SizedBox(
width: 200,
height: 50,
child: RaisedButton(
shape: new RoundedRectangleBorder(
borderRadius: new BorderRadius.circular(50.0)),
child: Text("Login"),
color: Colors.amber,
onPressed: () async {
setState(() => _isLoading = true);
var res = await _loginUser(
_emailController.text, _passwordController.text);
setState(() => _isLoading = false);
JsonUser user = JsonUser.fromJson(res);
if (user != null) {
Navigator.of(context).push(MaterialPageRoute<Null>(
builder: (BuildContext context) {
return new LoginScreen(
user: user,
);
}));
} else {
Scaffold.of(context).showSnackBar(SnackBar(
content:
Text("Email or password is incorrect")));
}
},
),
),
],
),
),
),
);
}
}
class LoginScreen extends StatelessWidget {
LoginScreen({#required this.user});
final JsonUser user;
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text("Login Screen")),
body: Center(
child: user != null
? Text("Logged IN \n \n Email: ${user.email} ")
: Text("Yore not Logged IN"),
),
);
}
}
for your app, you need to authenticate users over the api routes, which does not require CSRF tokens by default. you can achieve this using Laravel Passport or JWT auth

Resources