FATAL EXCEPTION: main Process: com.flutter_image, PID: 32038 kotlin.KotlinNullPointerException - flutter

I am getting this error and app crashes when I am pressing the button after compressing the image plzz help me
Thanks in advance
this is my code
onPressed: () async {
print('Selected Item = '+'$radioItemHolder');
if (radioItemHolder.contains('High')) {
print('High');
for (int i = 0;i < widget.image.length;i++) {
var path = await FlutterAbsolutePath.getAbsolutePath(
widget.image[i].identifier);
print("path");
print(path);
File compressedFile =await FlutterNativeImage.compressImage(path, quality:
90);
images.add(compressedFile);
GallerySaver.saveImage(compressedFile.path, albumName: 'Image Resizer')
.then((bool success) {
Fluttertoast.showToast(msg: "Image saved to gallary",toastLength:
Toast.LENGTH_SHORT,
gravity: ToastGravity.BOTTOM,
timeInSecForIosWeb: 5,
backgroundColor: Colors.red,
textColor: Colors.white,
fontSize: 16.0);
});
}
Navigator.push(context,
MaterialPageRoute(builder: (context) => Share_Convert_Iamge(image:
images)),
);
}}

First, download this package:
https://pub.dev/packages/common_utils
Then try to force wait for the compression to complete, before running the navigation logic. Just do this:
import 'package:common_utils/common_utils.dart';
///.........
Future runImageCompressionLogic() async {
for (int i = 0;i < widget.image.length;i++) {
var path = await FlutterAbsolutePath.getAbsolutePath(
widget.image[i].identifier);
print("path");
print(path);
await FlutterNativeImage.compressImage(path, quality:
90).then((compressedFile) {
if (!TextUtil.isEmpty(compressedFile)) {
images.add(compressedFile);
GallerySaver.saveImage(compressedFile.path,
albumName: 'Image Resizer')
.then((bool success) {
Fluttertoast.showToast(msg: "Image saved to
gallary",toastLength:
Toast.LENGTH_SHORT,
gravity: ToastGravity.BOTTOM,
timeInSecForIosWeb: 5,
backgroundColor: Colors.red,
textColor: Colors.white,
fontSize: 16.0);
});
});
}
}
}
}
///.....
onPressed: () async {
print('Selected Item = '+'$radioItemHolder');
if (radioItemHolder.contains('High')) {
print('High');
runImageCompressionLogic().whenComplete((){
Navigator.push(context,
MaterialPageRoute(builder: (context) =>
Share_Convert_Iamge(image:
images)),
});
);
}}

Related

Bad state: field does not exist within the DocumentSnapshotPlatform problem

I want to do the sign-in method and I face this run time error ,I don't know the reason cause it or how to solve it.
I want to checks all cases for login
my code is:
ElevatedButton(
onPressed: logIn,
child: StreamBuilder<User?>(
stream: FirebaseAuth.instance.authStateChanges(),
builder: (context, snapshot) {
// try{
print('inside bulder method');
if (snapshot.connectionState ==
ConnectionState.waiting) {
return const Center(
child: CircularProgressIndicator());
}
if (snapshot.hasData) {
print('have account');
return home();
} else {
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
content: const Text('Invalid email/password'),
backgroundColor: Colors.red.shade400,
margin: const EdgeInsets.fromLTRB(6, 0, 3, 0),
behavior: SnackBarBehavior.floating,
action: SnackBarAction(
label: 'Dismiss',
disabledTextColor: Colors.white,
textColor: Colors.white,
onPressed: () {},
)));
return Text('there is something error');
}
},
),)
and login method:
``Future<void> logIn() async {
print('inside login method');
if (_formKey.currentState!.validate()) {
try {
await FirebaseAuth.instance.signInWithEmailAndPassword(
email: emailController.text.trim(),
password: passwordController.text.trim(),
);
print('end try');
} catch (e) {
if (emailController.text.isNotEmpty &&
passwordController.text.isNotEmpty) {
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
content: const Text('Invalid email/password'),
backgroundColor: Colors.red.shade400,
margin: const EdgeInsets.fromLTRB(6, 0, 3, 0),
behavior: SnackBarBehavior.floating,
action: SnackBarAction(
label: 'Dismiss',
disabledTextColor: Colors.white,
textColor: Colors.white,
onPressed: () {},
)));
print("after check");
}
}
}
}
`
`
each textFormField is have the correct controller
and because of this problem I can't run this method correctly

how to disable button in flutter

I have an elevated button, to which i want to disable it after user hits the button, api gets called here. i have tried to setState but itseems not working. what else can i do to disable button.
hint: my concept i am working is that once ther users clicks the button, again the user should not be able to click again the same button.
Here is my code:
bool isEnable = false;
ElevatedButton.icon(
style: ButtonStyle(
backgroundColor: MaterialStateProperty.all(
const Color.fromARGB(255, 53, 121, 87)),
padding:
MaterialStateProperty.all(const EdgeInsets.all(20)),
textStyle: MaterialStateProperty.all(const TextStyle(
fontSize: 14, color: Colors.black))),
onPressed: qrdata.code != 9 && !isEnable
? () async {
setState(() {
isEnable = true;
});
var url = Uri.parse(
'${ApiConstants.baseUrl}${ApiConstants.updateEndpoint}');
var responseData = await http.put(url,
headers: ApiConstants.headers);
if (responseData.statusCode == 202) {
print(jsonDecode(responseData.body).toString());
// ignore: use_build_context_synchronously
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => Dashboard(
data: widget.data,
)),
);
}
//FocusManager.instance.primaryFocus!.unfocus();
// });
// setState(() {
// isEnable = false;
// });
}
:null,
// : () {},
icon: const Icon(
Icons.home_filled,
),
label: const Text('Entry',
style: TextStyle(
color: Colors.white,
)),
),
Please make sure variable qrdata.code and isEnable are initialized outside the build method. Every time when setState is called one or both the variables are getting reset.
The problem is whenever setState is pressed it is not rebuilding the button state. so to change the button state wrap your button with StatefulBuilder.
and please call your API in try catch.
class DisableButton extends StatefulWidget {
const DisableButton({Key? key}) : super(key: key);
#override
State<DisableButton> createState() => _DisableButtonState();
}
class _DisableButtonState extends State<DisableButton> {
bool isEnable = false;
int qrdata = 1;
#override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: StatefulBuilder(
builder:
(BuildContext context, void Function(void Function()) setState) {
return ElevatedButton.icon(
style: ButtonStyle(
backgroundColor: MaterialStateProperty.all(
const Color.fromARGB(255, 53, 121, 87)),
padding: MaterialStateProperty.all(const EdgeInsets.all(20)),
textStyle: MaterialStateProperty.all(
const TextStyle(fontSize: 14, color: Colors.black))),
onPressed: qrdata != 9 && !isEnable
? () async {
setState(() {
isEnable = true;
});
print(">>>> Button is disabled");
try {
final data = await http.get(
Uri.parse(
'https://jsonplaceholder.typicode.com/albums/1'),
);
if (!mounted) return;
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => NextPage(
data: data.body.toString(),
),
),
);
print("Api Data >>>> $data.body");
} catch (e) {
print("Error While fetching data");
}
setState(() {
isEnable = false;
});
print(">>>> Button is enabled");
}
: null,
// : () {},
icon: const Icon(
Icons.home_filled,
),
label: Text(isEnable ? "Disabled" : "Enabled",
style: const TextStyle(
color: Colors.white,
)),
);
},
),
),
);
}
}
class NextPage extends StatelessWidget {
const NextPage({Key? key, required this.data}) : super(key: key);
final String data;
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
body: Center(child: Text("Data : $data")),
);
}
}
The problem in your code is setting isEnable to true but not resting to false.
ElevatedButton.icon(
style: ButtonStyle(
backgroundColor: MaterialStateProperty.all(
const Color.fromARGB(255, 53, 121, 87)),
padding:
MaterialStateProperty.all(const EdgeInsets.all(20)),
textStyle: MaterialStateProperty.all(const TextStyle(
fontSize: 14, color: Colors.black))),
onPressed: qrdata.code != 9 && !isEnable
? () async {
setState(() {
isEnable = true;
});
var url = Uri.parse(
'${ApiConstants.baseUrl}${ApiConstants.updateEndpoint}');
var responseData = await http.put(url,
headers: ApiConstants.headers);
if (responseData.statusCode == 202) {
print(jsonDecode(responseData.body).toString());
// ignore: use_build_context_synchronously
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => Dashboard(
data: widget.data,
)),
);
}
//FocusManager.instance.primaryFocus!.unfocus();
// });
// setState(() { <---- Uncomment this code.
// isEnable = false;
// });
}
:null,
// : () {},
icon: const Icon(
Icons.home_filled,
),
label: const Text('Entry',
style: TextStyle(
color: Colors.white,
)),
),
Apply this code bellow:
You got error on double equal.
bool variable:
bool isDisabled = false;
Widget
ElevatedButton.icon(
style: ButtonStyle(
backgroundColor: MaterialStateProperty.all(
const Color.fromARGB(255, 53, 121, 87)),
padding:
MaterialStateProperty.all(const EdgeInsets.all(20)),
textStyle: MaterialStateProperty.all(const TextStyle(
fontSize: 14, color: Colors.black))),
onPressed: qrdata.code != 9 && !isDisabled
? () async {
setState(() {
isDisabled = true;
});
var url = Uri.parse(
'${ApiConstants.baseUrl}${ApiConstants.updateEndpoint}');
var responseData = await http.put(url,
headers: ApiConstants.headers);
if (responseData.statusCode == 202) {
print(jsonDecode(responseData.body).toString());
// ignore: use_build_context_synchronously
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => Dashboard(
data: widget.data,
)),
);
}
});
setState(() {
isDisabled = false;
});
}
:null,

Flutter Firebase auth phone and Firestore database

I would like when connecting by phone via OTP verification, to know if the account already exists and in this case retrieve its information. But if the account does not exist, create a collection in Firestore database with default information
My functional code for the telephone connection:
class AuthenticateScreen extends StatefulWidget {
#override
_AuthenticateScreenState createState() => _AuthenticateScreenState();
}
class _AuthenticateScreenState extends State<AuthenticateScreen> {
TextEditingController phoneController = TextEditingController();
TextEditingController otpController = TextEditingController();
FirebaseAuth auth = FirebaseAuth.instance;
bool otpVisibility = false;
User? user;
String verificationID = "";
String phoneNumber = "";
final DocumentReference documentReference =
FirebaseFirestore.instance.doc("users/{users}");
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(
"Phone Auth",
style: TextStyle(
fontSize: 30,
),
),
backgroundColor: Colors.indigo[900],
),
body: Container(
margin: EdgeInsets.all(10),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
TextField(
controller: phoneController,
decoration: InputDecoration(
hintText: 'Phone Number',
prefix: Padding(
padding: EdgeInsets.all(4),
child: Text('+33'),
),
),
maxLength: 10,
keyboardType: TextInputType.phone,
),
Visibility(
child: TextField(
controller: otpController,
decoration: InputDecoration(
hintText: 'OTP',
prefix: Padding(
padding: EdgeInsets.all(4),
child: Text(''),
),
),
maxLength: 6,
keyboardType: TextInputType.number,
),
visible: otpVisibility,
),
SizedBox(
height: 10,
),
MaterialButton(
color: Colors.indigo[900],
onPressed: () {
if (otpVisibility) {
verifyOTP();
} else {
loginWithPhone();
}
},
child: Text(
otpVisibility ? "Verify" : "Login",
style: TextStyle(
color: Colors.white,
fontSize: 20,
),
),
),
],
),
),
);
}
void loginWithPhone() async {
auth.verifyPhoneNumber(
phoneNumber: "+33" + phoneController.text,
verificationCompleted: (PhoneAuthCredential credential) async {
await auth.signInWithCredential(credential).then((value) {
print("You are logged in successfully");
});
},
verificationFailed: (FirebaseAuthException e) {
print(e.message);
},
codeSent: (String verificationId, int? resendToken) {
otpVisibility = true;
verificationID = verificationId;
setState(() {});
},
codeAutoRetrievalTimeout: (String verificationId) {},
);
}
void verifyOTP() async {
PhoneAuthCredential credential = PhoneAuthProvider.credential(
verificationId: verificationID, smsCode: otpController.text);
await auth.signInWithCredential(credential).then(
(value) {
setState(() {
phoneNumber = phoneController.text;
print("Connecte avec le compte " + "+33" + phoneController.text,);
user = FirebaseAuth.instance.currentUser;
});
},
).whenComplete(
() {
if (user != null) {
Fluttertoast.showToast(
msg: "Vous êtes maintenant connecté",
toastLength: Toast.LENGTH_SHORT,
gravity: ToastGravity.BOTTOM,
timeInSecForIosWeb: 1,
backgroundColor: Blue2Color,
textColor: Colors.white,
fontSize: 16.0,
);
Navigator.pushReplacement(
context,
MaterialPageRoute(
builder: (context) => Home_Screen(),
),
);
} else {
Fluttertoast.showToast(
msg: "La connexion a échoué.",
toastLength: Toast.LENGTH_SHORT,
gravity: ToastGravity.BOTTOM,
timeInSecForIosWeb: 1,
backgroundColor: Colors.red,
textColor: Colors.white,
fontSize: 16.0,
);
}
},
);
}
}
And here is my old code for login by mail to create a collection on firestore database :
class AuthenticationService {
final FirebaseAuth _auth = FirebaseAuth.instance;
AppUser? _userFromFirebaseUser(User? user) {
initUser(user);
return user != null ? AppUser(user.uid) : null;
}
void initUser(User? user) async {
if(user == null) return;
NotificationService.getToken().then((value) {
DatabaseService(user.uid).saveToken(value);
});
}
Stream<AppUser?> get user {
return _auth.authStateChanges().map(_userFromFirebaseUser);
}
Future signInWithEmailAndPassword(String email, String password) async {
try {
UserCredential result =
await _auth.signInWithEmailAndPassword(email: email, password: password);
User? user = result.user;
return _userFromFirebaseUser(user);
} catch (exception) {
print(exception.toString());
return null;
}
}

make function await flutter

I have this variable
dynamic _permission = true;
after clicked on button. I need to display sncakbar if _permission= false thats mean user has no permission to access the page else go to page.
but I faced an issue that _permission always equal true.
even if permission return false from api.
here is the code
Future<void> checkPermesssion() async {
String api_token = await getToken();
final response = await http.post(
Uri.parse(PermissionURL),
headers: {'Accept': 'application/json',
'Authorization': 'Bearer $api_token'
},
);
var permission = jsonDecode(response.body)['permission'];
setState(() {
_permission = permission;
});
}
and here is the button code
child: ElevatedButton(
onPressed: () {
checkPermesssion();
_permission ?
Navigator.of(context).push(
MaterialPageRoute(builder: (context) => page()))
:
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(
'You don\'t have permession to access this page '),
behavior: SnackBarBehavior.floating,
margin: EdgeInsets.all(50),
elevation: 30,
action: SnackBarAction(
label: 'Dismiss',
disabledTextColor: Colors.white,
textColor: Colors.yellow,
onPressed: () {
ScaffoldMessenger.of(context).hideCurrentSnackBar();
},
),
),
);
},
How can I do that please
Try this for button's code :
child: ElevatedButton(
onPressed: () async{
await checkPermesssion();
_permission ?
Navigator.of(context).push(
MaterialPageRoute(builder: (context) => page()))
:
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(
'You don\'t have permession to access this page '),
behavior: SnackBarBehavior.floating,
margin: EdgeInsets.all(50),
elevation: 30,
action: SnackBarAction(
label: 'Dismiss',
disabledTextColor: Colors.white,
textColor: Colors.yellow,
onPressed: () {
ScaffoldMessenger.of(context).hideCurrentSnackBar();
},
),
),
);
},

how to check if iap transactions are finished?

i am using https://pub.dev/packages/flutter_inapp_purchase this package for in-app-purchases. i sold credit but users can receive more credit then they paid, as shown in this video :
https://youtu.be/Bo5MQdi5wGY
how can i fix this bug ? help me , please. thanks.
All relevant lines of code are in below;
code:
Future<void> initPlatformState() async {
await Purchases.setDebugLogsEnabled(true);
await Purchases.setup("RowkOdfhhydoMREZKRckltCNUNzJqgnj");
String platformVersion;
try {
platformVersion = await FlutterInappPurchase.instance.platformVersion;
} on PlatformException {
platformVersion = 'Failed to get platform version.';
}
var result = await FlutterInappPurchase.instance.initConnection;
print('result: $result');
if (!mounted) return;
setState(() {
_platformVersion = platformVersion;
});
try {
String msg = await FlutterInappPurchase.instance.consumeAllItems;
print('consumeAllItems: $msg');
} catch (err) {
print('consumeAllItems error: $err');
}
_conectionSubscription =
FlutterInappPurchase.connectionUpdated.listen((connected) {
print('connected: $connected');
});
_purchaseUpdatedSubscription =
FlutterInappPurchase.purchaseUpdated.listen((productItem) {
// String deviceId = await PlatformDeviceId.getDeviceId;
dispose();
initPlatformState();
//FlutterInappPurchase.instance.finishTransaction(productItem);
if (productItem.productId == "oddinbetcredit10") {
print("CREDİT 10 !!!");
addCredit(deviceid, "10").then((value) => {
tipController.updateCredit(),
Fluttertoast.showToast(
msg: "Successfully loaded 10 credit !...",
toastLength: Toast.LENGTH_SHORT,
gravity: ToastGravity.SNACKBAR,
timeInSecForIosWeb: 1,
backgroundColor: Colors.red,
textColor: Colors.white,
fontSize: 16.0
)
});
} else if (productItem.productId == "oddinbetcredit20") {
print("CREDİT 20 !!!");
addCredit(deviceid, "20").then((value) => {
tipController.updateCredit(),
Fluttertoast.showToast(
msg: "20 credits successfully loaded !...",
toastLength: Toast.LENGTH_SHORT,
gravity: ToastGravity.SNACKBAR,
timeInSecForIosWeb: 1,
backgroundColor: Colors.red,
textColor: Colors.white,
fontSize: 16.0
)
});
} else if (productItem.productId == "oddinbetcredit50") {
print("CREDİT 50 !!!");
addCredit(deviceid, "50").then((value) => {
tipController.updateCredit(),
Fluttertoast.showToast(
msg: "50 credits successfully loaded !...",
toastLength: Toast.LENGTH_SHORT,
gravity: ToastGravity.SNACKBAR,
timeInSecForIosWeb: 1,
backgroundColor: Colors.red,
textColor: Colors.white,
fontSize: 16.0
)
});
} else if (productItem.productId == "oddinbetcredit100") {
print("CREDİT 100 !!!");
addCredit(deviceid, "100").then((value) => {
tipController.updateCredit(),
Fluttertoast.showToast(
msg: "100 crdits successfully loaded!...",
toastLength: Toast.LENGTH_SHORT,
gravity: ToastGravity.SNACKBAR,
timeInSecForIosWeb: 1,
backgroundColor: Colors.red,
textColor: Colors.white,
fontSize: 16.0
)
});
} else if (productItem.productId == "oddinbetcreditvip"){
isPremium = true;
Fluttertoast.showToast(
msg: "VIP successfully loaded!...",
toastLength: Toast.LENGTH_SHORT,
gravity: ToastGravity.SNACKBAR,
timeInSecForIosWeb: 1,
backgroundColor: Colors.red,
textColor: Colors.white,
fontSize: 16.0
);
}
});
_purchaseErrorSubscription =
FlutterInappPurchase.purchaseError.listen((purchaseError) {
print('purchase-error: $purchaseError');
});
}
Actually, this is a bug in this plugin and it is still open on Github
The reason why you are getting more credits is because the purchaseUpdated listener receives multiple callbacks on iOS and hence your addCredit() function is called multiple times.
As a workaround, you can use the transactionId as a flag and avoid calling the code inside the purchaseUpdated listener multiple times.
Add a check
if(lastTransactionId!=productItem.transactionId)
And initialize the lastTransactionId outside the if statement body
lastTransactionId = productItem.transactionId;
Complete code:
Declare a global variable
String lastTransactionId;
And then update your listener code with this
_purchaseUpdatedSubscription =
FlutterInappPurchase.purchaseUpdated.listen((productItem) {
// String deviceId = await PlatformDeviceId.getDeviceId;
if(lastTransactionId!=productItem.transactionId){ //Added this to avoid multiple callbacks for the same transaction
dispose();
initPlatformState();
//FlutterInappPurchase.instance.finishTransaction(productItem);
if (productItem.productId == "oddinbetcredit10") {
print("CREDİT 10 !!!");
addCredit(deviceid, "10").then((value) => {
tipController.updateCredit(),
Fluttertoast.showToast(
msg: "Successfully loaded 10 credit !...",
toastLength: Toast.LENGTH_SHORT,
gravity: ToastGravity.SNACKBAR,
timeInSecForIosWeb: 1,
backgroundColor: Colors.red,
textColor: Colors.white,
fontSize: 16.0
)
});
} else if (productItem.productId == "oddinbetcredit20") {
print("CREDİT 20 !!!");
addCredit(deviceid, "20").then((value) => {
tipController.updateCredit(),
Fluttertoast.showToast(
msg: "20 credits successfully loaded !...",
toastLength: Toast.LENGTH_SHORT,
gravity: ToastGravity.SNACKBAR,
timeInSecForIosWeb: 1,
backgroundColor: Colors.red,
textColor: Colors.white,
fontSize: 16.0
)
});
} else if (productItem.productId == "oddinbetcredit50") {
print("CREDİT 50 !!!");
addCredit(deviceid, "50").then((value) => {
tipController.updateCredit(),
Fluttertoast.showToast(
msg: "50 credits successfully loaded !...",
toastLength: Toast.LENGTH_SHORT,
gravity: ToastGravity.SNACKBAR,
timeInSecForIosWeb: 1,
backgroundColor: Colors.red,
textColor: Colors.white,
fontSize: 16.0
)
});
} else if (productItem.productId == "oddinbetcredit100") {
print("CREDİT 100 !!!");
addCredit(deviceid, "100").then((value) => {
tipController.updateCredit(),
Fluttertoast.showToast(
msg: "100 crdits successfully loaded!...",
toastLength: Toast.LENGTH_SHORT,
gravity: ToastGravity.SNACKBAR,
timeInSecForIosWeb: 1,
backgroundColor: Colors.red,
textColor: Colors.white,
fontSize: 16.0
)
});
} else if (productItem.productId == "oddinbetcreditvip"){
isPremium = true;
Fluttertoast.showToast(
msg: "VIP successfully loaded!...",
toastLength: Toast.LENGTH_SHORT,
gravity: ToastGravity.SNACKBAR,
timeInSecForIosWeb: 1,
backgroundColor: Colors.red,
textColor: Colors.white,
fontSize: 16.0
);
}
}
lastTransactionId = productItem.transactionId; //finally initialize your lastTransactionId with productItem.transactionId, outside the if statement
});
PS: You should call the await FlutterInappPurchase.instance.initConnection; method only once.
I hope this answer helps!