Reputation: 139
There are several similar questions about my problem, but the solution given in all of them doesn't work for me, so I try to open another question with the details for my problem. I hope somebody could help me.
Context: I am learning flutter & dart, and as a starter I would like to implement a simple app that consumes CRUD operations. I use REST API to access data on a MongoDB.
Problem: When I debug my code on web server as a web application it works fine. When I try to go on Android device with an apk, the server seems not to receive https get request, and client blocks on load indicator. As suggested in other questions, I made sure that the android uses_permissions for INTERNET were set in the AndroidManifest.xml.* I am pretty sure of this because the post http request to insert the data works fine also on the device. Further I use https as you can see below.
To build apk I use this command:
flutter build apk
I also tried this one as suggested in other questions:
flutter build apk --no-shrink
This does not help.
This is the widget ViewStoricoRifornimenti for fetching data in background, (like demo on flutter dev):
Future<List<Rifornimento>> fetchWelcomes(http.Client client) async {
final response = await client.get(
Uri.parse('https://car-statistics.herokuapp.com/rifornimenti'),
headers: <String, String>{
'Content-Type': 'application/json; charset=UTF-8',
'Access-Control-Allow-Origin': '*'
},
);
// Use the compute function to run parsePhotos in a separate isolate.
return compute(parseWelcomes, response.body);
}
List<Rifornimento> parseWelcomes(String responseBody) {
final parsed = Welcome.fromRawJson(responseBody);
return parsed.data;
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: FutureBuilder<List<Rifornimento>>(
future: fetchWelcomes(http.Client()),
builder: (context, snapshot) {
if (snapshot.hasError) print(snapshot.error);
return snapshot.hasData
? StoricoRifornimenti(items: snapshot.data!)
: Center(child: CircularProgressIndicator());
},
),
);
}
}
And here is the widget to display the results:
class _MyHomePageState extends State<MyHomePage> {
ViewStoricoRifornimenti vsr = new ViewStoricoRifornimenti(title: "Wow");
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
drawer: Drawer(
child: ListView(
padding: EdgeInsets.zero,
children: <Widget>[
DrawerHeader(
decoration: BoxDecoration(
color: Colors.blue,
),
child: Text('Menu'),
),
ListTile(
title: Text('Storico Rifornimenti'),
onTap: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => vsr),
);
},
),
],
),
)
}
}
Am I doing something wrong? Why in debug on the Web Application I have no errors while on device I can't get http response?
How could I debug this kind of problem?
Thanks to everybody will help me.
Upvotes: 13
Views: 14006
Reputation: 42
I had a similar problem, my app was working fine on web but not on android, I fixed that by adding a null check to my class.fromMap()
:
class(id: json["id"] ?? '',);
Upvotes: 0
Reputation: 105
I think your problem is that, from Android 9 you need to add a network_security_config.xml file in your xml directory in android/res/ folder.
The content for network_security_config.xml is as follows:
<domain-config cleartextTrafficPermitted="true">
<domain includeSubdomains="true">yourdomain.com</domain>
<domain includeSubdomains="true">yourdomain2.com</domain>
</domain-config>
For more information head to this article : Fix Clear Text Traffic
And in your AndroidManifest.xml file inside tag add these lines:
android:usesCleartextTraffic="true"
android:networkSecurityConfig="@xml/network_security_config"
That's what worked for me. Please correct me if I am wrong and also let me know that fixed your problem.
Upvotes: 1
Reputation: 516
I had to adjust the linting settings to enforce no implicit type castings. It seems to be handled differently in the release build.
I ran flutter pub add lints --dev
to get cautioned about implicit type casts in the serialization line fromJson
and toJson
in my model classes this fixed the issues.
I started with adding a file to my project root called analysis_options.yaml
with the following content:
analyzer:
strong-mode:
implicit-casts: false
implicit-dynamic: false
The lints package seems to have this and even more rules.
Upvotes: 0
Reputation: 2319
Make sure you add the below code to your manifest.
First, make sure you add internet permission to manifest
<uses-permission android:name="android.permission.INTERNET" />
Seconds make sure you added usesCleartextTraffic true that will make sure if your API endpoint is not secure still you will able to call API.
<application
android:usesCleartextTraffic="true">
Upvotes: 24