How to prevent flutter app from crashing after Dio error? - flutter

I am using the flutter-dio package to make HTTP requests and have made a wrapper on it from my convenience like so
Future<dynamic> post(String uri, dynamic body, {String authKeyCust}) async {
authKey = await SecureStorage.getAuthKey();
try {
Response response = await dio.post(
uri,
data: body,
options: Options(headers: {"authkey": authKeyCust ?? "$authKey"}),
);
return response.data;
} on DioError catch (error) {
print('error: $error');
} on SocketException catch(error) {
print('No net');
}
}
All I want is the app to not crash/pause on exception when any error occurs.

I also had the same problem.
First, try to run it from command prompt with flutter run see if there is occurring any problem or not.
If the command prompt is showing no problem & your app is running smoothly then you have to check the IDE. If you are using VSCode then switch to Debug is side bar, see which options are ticked in Breakpoint section.
If All Exceptions is ticked then the debugger will pause on every exception. Uncheck both All Exceptions & Uncaught Exceptions then try refresh restart.
Hope this will solve your problem.

Related

Flutter Chrome Debugging: API calls don't work at all

I'm developing a simple web/Android Flutter App. Everything works fine on Android, but when I try debugging it on Chrome (web-javascript), none of my API calls work.
Debugger stops in ticker.dart > TickerFuture > _complete() and this message appears in the console, and the API call continues forever.
ChromeProxyService: Failed to evaluate expression '_primaryCompleter'
I've tried using CORS and try catch blocks to see if i can get more info about the error.
This is an example API call:
Future<bool> login(LoginData l) async {
try {
Uri url = Uri.parse(baseUrl + "/login/");
final response = await http.post(url,
body: {"email": l.name, "password": l.password},
headers: {"Access-Control-Allow-Origin": "*"});
if (response.statusCode == 200) {
return response.body == "true";
} else {
throw Exception('Failed to load books');
}
} catch (e) {
print(e);
throw Exception('Failed to load books');
}
}
There were some issues with debugging in Chrome after Chrome v100 released.
Flutter 2.10.5 was released to fix some of these issues:
https://github.com/flutter/flutter/wiki/Hotfixes-to-the-Stable-Channel#2105-april-18-2022
flutter/101224 - Flutter web debugger fails when using chrome 100 or greater.

Is it safe to use print() with dart?

Is it safe to still use print() in dart (flutter 2.5.1), if not what command should I use to print errors?
if (query != null) {
_query.addAll(query);
}
return await dio.get(_url, queryParameters: _query);
} on DioError catch (e) {
print('DioError:$e');
}
What you are getting is just a warning. You should throw errors instead of printing it.
if (query != null) {
_query.addAll(query);
}
return await dio.get(_url, queryParameters: _query);
} on DioError catch (e) {
throw Exception(e);
}
If you're inside a widget ,
Use debugPrint('data') , because it'll only show data in debug mode and will not run in release mode. So, it'll save you a lot of time.
Otherwise , you can also use log('data') , it'll show whole response in logging pattern in console.

Open an app in flutter based on the url provided in the email sent for verification

So I have been working on a flutter app and once the user registers through my app they are sent an email for the verification of their account. Once the url in the link is tapped they are verified. Now after their verification,the users must be redirected to the app. I looked into firebase dynamic links but in all of the articles,they were trying to share their app by generating a link. Is there a way I can implement this? Thanks in advance!
Use this package
https://pub.dev/packages/uni_links
For getting the link when the app is started.
This is the case in which your app was in the closed state.
Future<Null> initUniLinks() async {
// Platform messages may fail, so we use a try/catch PlatformException.
try {
String initialLink = await getInitialLink();
// Parse the link and warn the user, if it is not correct,
// but keep in mind it could be `null`.
} on PlatformException {
// Handle exception by warning the user their action did not succeed
// return?
}
}
For listening to link clicks. This is for the case when your app is already open and you click the link.
_sub = getLinksStream().listen((String link) {
// Parse the link and warn the user, if it is not correct
}, onError: (err) {
// Handle exception by warning the user their action did not succeed
});
// NOTE: Don't forget to call _sub.cancel() in dispose()
}
Usually, you need to implement both of them together since your app may be in the closed state or open state while you click the link.
Future<Null> initUniLinks() async {
try {
String initialLink = await getInitialLink();
} on PlatformException {
}
_sub = getLinksStream().listen((String link) {}, onError: (err) {});
}}

How to use Steam (OpenId) to login into my Firebase powered Flutter app?

I'm building a Flutter app and I want users to be able to login through Steam (OpenId).
The app is powered by Firebase.
I'm pretty new to the whole OpenId world and I've read into it but I'm still not getting it.
I found that Firebase Supports signinWithCustomToken so I think I should get the Steam OpenId to get me one of those.
I also found two packages which might help me but I couldn't get those to work either:
https://pub.dev/packages/openid_client
https://pub.dev/packages/steam_login
If tried the following sample from the openid_client package:
_authenticate(Uri uri, String clientId, List<String> scopes) async {
try {
var issuer = await Issuer.discover(uri);
var client = Client(issuer, clientId);
print('CLAIMS:');
print(issuer.claimsMap);
urlLauncher(String url) async {
if (await canLaunch(url)) {
await launch(url, forceWebView: true);
} else {
throw 'Could not launch $url';
}
}
var authenticator = Authenticator(client,
scopes: scopes, port: 4000, urlLancher: urlLauncher);
var c = await authenticator.authorize();
closeWebView();
print(await c.getUserInfo());
}catch (err) {
print(err);
}
}
But I have no idea what to give as the uri, clientId and scopes.
For the uri I've tried https://steamcommunity.com/openid but when I try this I'm getting an error that it tried to Json.parse a xml response.
I've also tried the example for the steam_login package here, but that does nothing and doesn't feel like it should work within a Flutter app (even though the package states it Flutter compatible).
So if anybody could explain to me how I could achieve this with a working sample that would be great.
If I get this to work I'm planning on creating a tutorial/guide for it for others.

Flutter getting an exception when calling queryPastPurchases (in_app_purchase plugin): Cannot find receipt for the current main bundle

I'm trying to utilise the in_app_purchase plugin (https://pub.dev/packages/in_app_purchase) for my Flutter App.
Calling a queryProductDetails(ids) works just fine,
but when calling the queryPastPurchases() I get the following exception:
PlatformException (PlatformException(storekit_no_receipt, Cannot find receipt for the current main bundle., null))
Seems like this is the source for the exception:
https://github.com/flutter/plugins/blob/master/packages/in_app_purchase/ios/Classes/FIAPReceiptManager.m
Worth mentioning:
I've setup an IAP in App-Store-Connect.
This IAP hasn't been sent for Apple approval yet.
App is in development, tested using TestFlight with beta testers.
Another issue is that this exception doesn't get cought in the try-catch statement (see code below), but only by the environment when checking the "All Exceptions" option in VSCode...
Tested on Emulator and real device.
[UPDATE]:
Added a breakpoint to the objective-c code of the plugin, and saw that the receiptURL refers to "sandboxReceipt". So maybe it's because I don't use sandbox users?
Future<void> _getPastPurchases() async {
try {
final QueryPurchaseDetailsResponse response = await InAppPurchaseConnection.instance.queryPastPurchases();
if (response.error != null) {
// Handle the error
print(response.error.toString());
}
print('response = ' + response.toString());
for (PurchaseDetails purchase in response.pastPurchases) {
if (Platform.isIOS) {
//InAppPurchaseConnection.instance.completePurchase(purchase);
}
}
setState(() {
_purchases = response.pastPurchases;
});
} on PlatformException catch(err) {
print(err.toString());
}
catch (err) {
print(err.toString());
}
}