Flutter: how to fix url on flutter? - flutter

I wrote a code that after logging in with the MaterialPageRoute command takes you to the "main" page. But I'm afraid that you can also enter without logging in, by changing the url. Do you know how I can solve? if it is not clear what I want to do ask in the comments, however I would like to avoid that through the url from the login you can go to the main page
FlatButton(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(2)),
padding: EdgeInsets.fromLTRB(widthButton, 5, widthButton, 5),
color: Colors.white,
//Verifica del nome utente e password che se corretto porta alla pagina princiapale
onPressed: () async {
var username = _usernameController.text;
var password = _passwordController.text;
var jwt = await attemptLogIn(username, password);
if (jwt != '') {
window.localStorage["csrf"] = jwt;
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => HomePage.fromBase64(jwt)));

On your non-protected screens
Maybe use the Offstage widget to deliver a message asking the user to login with a link to redirect them to the login page. On the offstage: argument pass a bool that is only true if the user successfully logs into the app.
final GlobalKey _key = GlobalKey();
bool _isLoggedIn = true;
Size _getFlutterLogoSize() {
final RenderBox renderLogo = _key.currentContext!.findRenderObject()! as RenderBox;
return renderLogo.size;
}
#override
Widget build(BuildContext context) {
return Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Offstage(
offstage: _isLoggedIn,
child: FlutterLogo(
key: _key,
size: 150.0,
),
),
Text('Flutter logo is offstage: $_offstage'),
ElevatedButton(
child: const Text('Toggle Offstage Value'),
onPressed: () {
setState(() {
_isLoggedIn = !_isLoggedIn;
});
},
),
if (_isLoggedIn)
ElevatedButton(
child: const Text('Get Flutter Logo size'),
onPressed: () {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text('Flutter Logo size is ${_getFlutterLogoSize()}'),
),
);
}
),
],
);
}
Source of sample code on api.flutter.dev
Try the sample code in the website above by running the code and clicking the buttons that show and hide the logo. You need to figure out how this would fit into your code since you are only showing a small part of the code.

Related

How to take screenshot of entire screen outside of your FLUTTER DESKTOP app(mostly for Windows OS)?

I'm new to flutter. Now I am able to take screenshot for my entire desktop app screen using Screenshot package & storing that image to local storage.
But my requirement is to capture the screenshot of entire screen of the window, like if 2 applications are opened(1 Flutter + 1 any other app e.g. browser) in 1 screen, then we can able to take whole screen's screenshot not only flutter app.
Please help me on how to take entire window's screenshot in Windows OS desktop app?
If it's not possible directly from Flutter, then how to achieve this by implementing some native code with Flutter?
check this completely working as expected
bool _isAccessAllowed = false;
CapturedData? _lastCapturedData;
#override
void initState() {
super.initState();
_init();
}
void _init() async {
_isAccessAllowed = await ScreenCapturer.instance.isAccessAllowed();
}
void _handleClickCapture(CaptureMode mode) async {
Directory directory = await getApplicationDocumentsDirectory();
String imageName =
'Screenshot-${DateTime.now().millisecondsSinceEpoch}.png';
String imagePath =
'${directory.path}/screen_capturer_example/Screenshots/$imageName';
_lastCapturedData = await ScreenCapturer.instance.capture(
mode: mode,
imagePath: imagePath,
silent: true,
);
if (_lastCapturedData != null) {
// ignore: avoid_print
// print(_lastCapturedData!.toJson());
} else {
// ignore: avoid_print
print('User canceled capture');
}
setState(() {});
}
Widget _buildBody(BuildContext context) {
return PreferenceList(
children: <Widget>[
if (Platform.isMacOS)
PreferenceListSection(
children: [
PreferenceListItem(
title: const Text('isAccessAllowed'),
accessoryView: Text('$_isAccessAllowed'),
onTap: () async {
bool allowed =
await ScreenCapturer.instance.isAccessAllowed();
BotToast.showText(text: 'allowed: $allowed');
setState(() {
_isAccessAllowed = allowed;
});
},
),
PreferenceListItem(
title: const Text('requestAccess'),
onTap: () async {
await ScreenCapturer.instance.requestAccess();
},
),
],
),
PreferenceListSection(
title: const Text('METHODS'),
children: [
PreferenceListItem(
title: const Text('capture'),
accessoryView: Row(children: [
CupertinoButton(
child: const Text('region'),
onPressed: () {
_handleClickCapture(CaptureMode.region);
},
),
CupertinoButton(
child: const Text('screen'),
onPressed: () {
_handleClickCapture(CaptureMode.screen);
},
),
CupertinoButton(
child: const Text('window'),
onPressed: () {
_handleClickCapture(CaptureMode.window);
},
),
]),
),
],
),
if (_lastCapturedData != null && _lastCapturedData?.imagePath != null)
Container(
margin: const EdgeInsets.only(top: 20),
width: 400,
height: 400,
child: Image.file(
File(_lastCapturedData!.imagePath!),
),
),
],
);
}
// screen shot taken by the App.
You might try using this package: screen_capturer. It works on Windows, Linux and MacOS.
From the docs:
Example of usage:
import 'package:screen_capturer/screen_capturer.dart';
CapturedData? capturedData = await screenCapturer.capture(
mode: CaptureMode.screen, // screen, window
imagePath: '<path>',
);
CaptureMode.screen is to capture the entire screen.
The screenshot package which you mention is only for taking screenshots for widgets of your app not of whole screen.

How to render image from Firebase without rebuilding?

I'm trying to implement profile image picking in my flutter app using Firebase Storage. I use image_picker to get the image and upload it to Firebase, get the download link and add the download link to the imgsrc field in the cloud firestore, from where I can render the NetworkImage.
Center(
child: Stack(
children: [
buildImage(),
Positioned(
bottom: 5,
right: 5,
child: GestureDetector(
onTap: showPhotoAlertDialog,
child: buildEditIcon(Color(0xff407bff))),
),
],
),
),
How can I get the default Icons.person kind image for when the user has no profile image, and get the image from the database otherwise?
The code I'm using right now is as follows:
Widget buildImage() {
return CircleAvatar(
backgroundImage: NetworkImage(loggedInUser.imgsrc ??
'https://th.bing.com/th/id/R.945f33b643f2ceffcdae90fb57c61854?rik=XcI0SYBgSefoCA&riu=http%3a%2f%2fgetdrawings.com%2ffree-icon-bw%2fanonymous-avatar-icon-19.png&ehk=5n%2buJG66CeLQZsmhaMt8gag5rXuM3TdebAL6W35K1E4%3d&risl=&pid=ImgRaw&r=0'),
backgroundColor: Colors.grey[350],
radius: 100,
);
}
I created an Alert Dialog widget to choose whether to choose the image from camera or from the gallery.
showPhotoAlertDialog() {
AlertDialog alert = AlertDialog(
title: Text("Upload from"),
content: Column(
mainAxisSize: MainAxisSize.min,
children: [
TextButton(
onPressed: () {
imageFromCamera()
.then((value) => uploadFile())
.whenComplete(() => postSource());
setState(() {}); ----->
},
child: Text("Upload from camera"),
),
TextButton(
onPressed: () {
imageFromGallery().then((value) => uploadFile());
postSource();
setState(() {});
},
child: Text("Upload from gallery"),
)
],
),
);
showDialog(
context: context,
builder: (BuildContext context) {
return alert;
},
);
}
To upload the image to storage and post the source to cloud firestore, I use the following methods:
Future uploadFile() async {
if (file == null) return;
final fileName = path.basename(file!.path);
final destination = 'files/$fileName';
task = FirebaseApi.uploadFile(destination, file!);
setState(() {});
if (task == null) return;
final snapshot = await task!.whenComplete(() {});
urlDownload = await snapshot.ref.getDownloadURL();
print('Download-Link: $urlDownload');
}
postSource() async {
FirebaseFirestore firebaseFirestore = FirebaseFirestore.instance;
await firebaseFirestore
.collection("users")
.doc(user?.uid)
.update({'imgsrc': urlDownload});
}
The link gets uploaded properly and I'm able to get the link in my NetworkImage, but it doesn't get rendered immediately. I have to close the parent drawer and open it again to get it. I call setState(){} as well after posting the source, but it doesn't make any difference. How can I get the image without having to close and open the drawer?
Any help would be appreciated!
Thanks
You also have to update image in model class or in this imgsrc also just add this line above setState in onPressed of TextButton.
loggedInUser.imgsrc = urlDownload;

I want to update the app version in playstore to show a message dialog to user

I am new flutter .I want to update new version app in playstore to show a message dialog to user to update the new version and I used the plugin version_check 0.2.0.
When the user has already updated, but it still displays Message dialog the same. How not to show message dialog after update.Who can help me?
This my Code
This my Code
This my Code
As everything is not clear in the question, you should follow given steps to achieve the same.
Step 1. Go to Remote Config in firebase and add few parameters shown in the image and then publish it.
Step 2. Create a function VersionCheck and _showVersionDialog as follows:
versionCheck(){
//Get Current installed version of app
WidgetsBinding.instance.addPostFrameCallback((_) async {
final PackageInfo info = await PackageInfo.fromPlatform();
double currentVersion = double.parse(info.version.trim().replaceAll(".", ""));
//Get Latest version info from firebase config
final RemoteConfig remoteConfig = await RemoteConfig.instance;
try {
// Using default duration to force fetching from remote server.
await remoteConfig.fetch(expiration: const Duration(seconds: 0));
await remoteConfig.activateFetched();
remoteConfig.getString('force_update_current_version');
double newVersion = double.parse(remoteConfig
.getString('force_update_current_version')
.trim()
.replaceAll(".", ""));
if (newVersion > currentVersion) {
setState(() {
versionCode = remoteConfig.getString('force_update_current_version');
aboutVersion = remoteConfig.getString('update_feature');
});
_showVersionDialog(context);
}
} on FetchThrottledException catch (exception) {
// Fetch throttled.
print(exception);
} catch (exception) {
print('Unable to fetch remote config. Cached or default values will be '
'used');
}
});
}
_showVersionDialog(context) async {
await showDialog<String>(
context: context,
barrierDismissible: false,
builder: (BuildContext context) {
String title = "Update Available";
String message =
"About Update: \n";
return ButtonBarTheme(
data: ButtonBarThemeData(alignment: MainAxisAlignment.center),
child: new AlertDialog(
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(30)),
title: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(title),
Text("v"+versionCode),
],
),
content: Container(
height: 80,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(message,style: TextStyle(fontWeight: FontWeight.bold),),
Text(aboutVersion),
],
),
),
actions: <Widget>[
Padding(
padding: const EdgeInsets.all(8.0),
child: RaisedButton(
child: new Text(
'Update',
style: TextStyle(color: Colors.white),
),
color: Color(0xFF121A21),
shape: new RoundedRectangleBorder(
borderRadius: new BorderRadius.circular(30.0),
),
onPressed: () {
_launchURL(PLAY_STORE_URL);
},
),
),
],
),
);
},
);
}
Step 3. Call VersionCheck in init function of your main screen as follows.
#override
void initState() {
Future.delayed(const Duration(milliseconds: 5000), () {
if(mounted){
setState(() {
versionCheck();
});
}
});
super.initState();
}
Step 4. Whenever you want the update dialog to appear on screen just increase the version code value in remote config of firebase than your actual version code value.
This will help you to achieve what you want.

My flutter app, generate multiple register in DB when I press button once

I have an app that contains a form. First, you have to authenticate with your ID, a function checks the date of your last register (if you don't register today, you'll pass. If not you can not log into the form screen). Second, you register your symptoms once a day(restriction of the app), press "ENVIAR(send)" and a POST method storages your data in a DB. It's simple.
In theory, I should see one register per person per day. Now the number of devices with my app installed has increased I can see multiple registers per person in some cases. Curiously the problem happens in just some devices. I cannot detect the problem because with my phone I've never had these kinds of problems (HUAWEI P30 LITE).
I try to debug my code, but it all works perfectly. Could you help or advise me on how to solve this problem, please?
PDT: when I press the button "SEND", the function _submit() is executed, which allows POST the data in the DB. Additionally, to verify the systems works right, I use a developer account with credential "000000000". I had to eliminate many lines, but these are the most important.
Have a nice day.
Thanks
I attach the code:
class Tamizaje1Page extends StatefulWidget {
#override
_Tamizaje1PageState createState() => _Tamizaje1PageState();
}
class _Tamizaje1PageState extends State<Tamizaje1Page> {
final usuariosProvider = new UsuariosProvider();
final appProvider = new AppProvider();
final formKey = GlobalKey<FormState>();
final productoProvider = new ProductosProvider();
ProductoModel producto = new ProductoModel();
AppModel app = new AppModel();
#override
Widget build(BuildContext context) {
final bloc = Provider.of(context);
mostrarPosision();
return Scaffold(
appBar: AppBar(
automaticallyImplyLeading: false,
title: Center(child: Text('Cuestionario Diario')),
),
body: WillPopScope(
onWillPop: (){Navigator.pushAndRemoveUntil(context, MaterialPageRoute(builder: (context) => LoginPage()), (route) => false);},
child: SingleChildScrollView(
child: Container(
padding: EdgeInsets.all(15.0),
child: Form(
key: formKey,
child: Column(
children: <Widget>[
_crearBoton1(context),
],
),
),
),
),
),
);
}
Widget _crearBoton1( BuildContext context) {
final size = MediaQuery.of(context).size;
return ButtonTheme(
minWidth: size.width*0.2,
height: size.height*0.07,
focusColor: colorApp,
child: RaisedButton(
child: Container(padding: EdgeInsets.symmetric( horizontal: 80.0, vertical: 15.0),child: Text('Enviar', style: TextStyle(color: Colors.white,fontSize: 16.0),)),
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(25.0),side: BorderSide(color: Colors.transparent,width: 2.0)),
elevation: 0.0,
color: colorApp,
textColor: Colors.white,
onPressed: ( _guardando ) ? null : _submit,
),
);
}
//THIS FUNCTION SENDS THE DATA WHEN PRESS THE BUTTON
_submit() async {
_noVisibleData();
if ( !formKey.currentState.validate() ) return;
formKey.currentState.save();
if(producto.nroDoc!="000000000" && _currentPosition != null && ((producto.meSiento=='1' && app.diagnostico!='-1') || (producto.meSiento=='0'))){
bool permtirenvioToDB= await productoProvider.crearProducto(producto); //envia los datos
if(permtirenvioToDB==true){
_alertaDeEnvio(context, envio1);
await enviarGMAIL();
appProvider.crearApp(app);
Navigator.push(context, MaterialPageRoute(builder: (context) => AlertPage()));
}else{
contarIntetentosEnvioDB++;
if(contarIntetentosEnvioDB<5)_soloMensaje(context,"Se ha producido un error al enviar el formulario. Por favor... ¡Inténtalo nuevamente!","assets/alerta0/a0i1.svg",80.0);
else _soloMensaje(context,"Por favor, ¡Comuníquese con el área de Tecnologías de la Información!","assets/alerta0/a0i3.svg",80.0);
}
}else{
_alertaDeEnvio(context, envio1);
print('Prueba de desarrollador');
Navigator.push(context, MaterialPageRoute(builder: (context) => AlertPage()));
}
}
}
Thanks, i debugged many option and realised the errors occurs because i have 3 future functions wich execute when i press the button (inside the butto widget). I created i new page with an additional #averride before Widget build exclusive to execute future functions, and it works good.
class _MailDBSendState extends State<MailDBSend> {
#override
void initState() {
super.initState();
_dataBase();
_sendMail();
}
.
.
.
.
#override
Widget build(BuildContext context) {
return Scaffold(
body: Stack(

How to show Valid or Invalid Snackbar when user enters the credential in Flutter?

When the user enter wrong credentials the snackbar should show Login Failed and when right page should show successfully logged in snackbar.
I have used firebase to authentication.
final _formKey = GlobalKey<FormState>();
TextEditingController _emailLoginFormTextEditingController = new TextEditingController();
TextEditingController _passwordLoginFormTextEditingController = new TextEditingController();
void initState() {
super.initState();
}
_signInUsingFirebase(String email, String password) {
FirebaseAuth firebaseAuth = FirebaseAuth.instance;
firebaseAuth.signInWithEmailAndPassword(email: email, password: password)
.then((AuthResult authResult) {
FirebaseUser user = authResult.user;
Navigator.of(context).push(MaterialPageRoute(
builder: (context) => HomePage(email: email, userid: user.uid,),
));
}).catchError((error) {
debugPrint(error);
});
}
Widget _loginPageSaffoldBody(BuildContext context) {
return Form(
key: _formKey,
child: ListView(
padding: EdgeInsets.all(32),
children: <Widget>[
TextFormField(
controller: _emailLoginFormTextEditingController,
),
TextFormField(
controller: _passwordLoginFormTextEditingController,
),
RaisedButton(
onPressed: () {
// If statement is validating the input fields.
if (_formKey.currentState.validate()) {
_signInUsingFirebase(_emailLoginFormTextEditingController.text,
_passwordLoginFormTextEditingController.text);
Scaffold.of(context).showSnackBar( //Snackbar for Succesfull
SnackBar(
content: Text(
"Succesfull",
),
),
);
}
else{
Scaffold.of(context).showSnackBar( //Snackbar for unsuccesfull
SnackBar(
content: Text(
"Unsuccesfull",
),
),
);
}
},
child: Row(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Icon(
Icons.lock_open,
),
SizedBox(width: 4),
Text(
"Submit",
),
],
),
), // Submit Button
],
),
);
}
A little out of context question I also want to keep user logged in once they enter the credentials till they login in i want to use shared preference but unable to understand how if u can provide any link might help
Thank You !
For start, check the official documentation, where some basic examples provided by Google itself.
In your case, retrieve the response of the Firebase Login and push it to the separate service, which will create the needed snack bar.
For the saving login - yes, you can use shared_preferences and save two separate strings - one for login, one for the password. When initially logged in, save those, and when a user opens an app once again, first check shared_preferences for the case of needed data, and if it exists - just push it to function
Feel free to ask anything :3
Declare a Key:- key:_scaffoldKey, in scaffold
Declare final _scaffoldKey = GlobalKey<ScaffoldState>();
Then simply initialize it in .catchError((error) and .then((AuthResult authResult)
final snackBar = SnackBar(content: Text("Succesfully LoggedIn"));
_scaffoldKey.currentState.showSnackBar(snackBar);