I'm following the Persist data with SQLite tutorial from the Flutter Dev website, and I'm trying to open a database connection using async, but I keep getting the error Unexpected text 'await'. Even when I copy the code directly from the tutorial I'm still getting the same error.
This is my full file:
import 'dart:async';
import 'package:path/path.dart';
import 'package:sqflite/sqflite.dart';
// Open the database and store the reference.
final Future<Database> database = openDatabase(
join(await getDatabasesPath(), 'doggie_database.db'),
);
As far as I can tell I'm using the keyword correctly, so why is the compiler complaining?
I'm using Dart 2.7.0-dev.2.1 if that makes a difference.
This seems like an issue with asynchronicity. It's strange that an example from the official documentation is leading you into this mistake. Directly assigning a variable outside of a method that would need to be async. Try this:
final Future<Database> database = getDatabasesPath().then((String path) {
return openDatabase(join(path, 'doggie_database.db'));
});
For future reference, the reason why the OP's code wasn't working was because he was running it outside of the main() Flutter method, which is async in the example provided by the Flutter documentation: https://flutter.dev/docs/cookbook/persistence/sqlite#example
Related
I have a project which uses flutter_libserialport library on macOS.
I am modifying it to work on web however this library does not work on web.
I am building a web implementation using navigator.serial in javascript which works fine.
However when I attempt to build the project for web I get the following error
/opt/homebrew/Caskroom/flutter/2.2.3/flutter/.pub-cache/hosted/pub.dartlang.org/libserialport-0.2.0+3/lib/src/config.dart:25:8: Error: Not found: 'dart:ffi'
import 'dart:ffi' as ffi;
This makes sense since FFI is not available on web.
But I don't even need the libserialport library on web any way.
How can I get flutter to ignore it?
I tried this however it doesn't contain information on how to exclude a package.
It also does not contain information on how to ignore it specifically for web. It seems to just ignore it in general.
Maybe you should guard your usages of libserialport with the kIsWeb predicate like following:
if(!kIsWeb){
// libserialport code execution here
}
I searched a lot as well and didn't find a way you can do that, I think this should be handled by the package itself not the package's users like in path_provider for instance.
As a workaround I have created a dummy libserialport's SerialPort class for web only as follows:
dummy_serialport.dart:
class SerialPort {
final String name;
static List<String> availablePorts = ['dummy'];
static SerialPortError? lastError;
SerialPort(this.name);
bool openReadWrite() {
return false;
}
}
class SerialPortError {}
// add more properties and functions as needed
main.dart:
import 'package:libserialport/libserialport.dart'
if (dart.library.html) './dummy_serialport.dart'
if (dart.library.io) 'package:libserialport/libserialport.dart';
....
if (!kIsWeb) {
final name = SerialPort.availablePorts.first;
final port = SerialPort(name);
if (!port.openReadWrite()) {
print(SerialPort.lastError);
exit(-1);
}
}
....
....
It's bad, I know :( but it works! maybe you can contact the package author to get more insight and if opening a PR where the interfaces are separated from the FFI implementation so that importing the classes wouldn't break web or something.
I'm working on flutter app that uses php apis for server and sqlite for local data.
The problem is with "compute()".
Here is the explanation :
I have three functions that receives data from api on the server, then add the data to my local database (sqlite) table.
First function to get data from server.
Future<List<Map<String, dynamic>>> getServerData(int vers)async {
//my code
}
Second function to insert data into local database:
Future<int> addNewData(List<Map<String, dynamic>>)async {
//my code
}
Third function to call the first and second function:
Future<bool> checkServerData(int vers)async {
List<Map<String, dynamic>> sdt= await getServerData(vers);
int res=await addNewData(sdt);
if(res>0) return true;
else return false;
}
I want to call the third function in a compute function:
compute(checkServerData, 2);
When did that I found this error:
null check operator used on null value.
Note*:
If I used it without calling local database it works good.
The error appears if I called the database to insert data into.
When I searched about this issue I found that it's not allowed to access any resources which generated in one thread from another thread. But I didn't understand exactly how to resolve it or how to use another way that do the same idea.
After searching about the issue specified, I found those workaround solutions:
1: if the process is very important to work in background, you can use the Isolate package classes and functions which allow all isolated processes or contexts to share data between them as messages sending and receiving. But it's something complex for beginners in flutter and dart to understand these things, except those who know about threading in another environments.
To now more about that I will list here some links:
Those for flutter and pub documentation:
https://api.flutter.dev/flutter/dart-isolate/dart-isolate-library.html
https://api.flutter.dev/flutter/dart-isolate/Isolate-class.html
https://pub.dev/packages/flutter_isolate
This is an example in medium.com website:
https://medium.com/flutter-community/thread-and-isolate-with-flutter-30b9631137f3
2: the second solution if the process isn't important to work on background:
using the traditional approaches such as Future.builder or async/await.
You can know more about them here:
https://www.woolha.com/tutorials/flutter-using-futurebuilder-widget-examples
https://dart.dev/codelabs/async-await
and you can review this question and answers in When should I use a FutureBuilder?
I'm using Flutter-web and I want to export a pdf. I'm using the pdf package and i'm trying to implement a simple example from their documentation. To be more specific, I have a file called export_pdf.dart and the code inside it is the following.
import 'package:pdf/pdf.dart';
import 'package:pdf/widgets.dart';
import 'package:universal_io/io.dart';
import 'package:path_provider/path_provider.dart';
exportPdf() async {
final pdf = Document();
pdf.addPage(Page(
pageFormat: PdfPageFormat.a4,
build: (Context context) {
return Center(
child: Text("Hello World"),
); // Center
})); // Page
final output = await getTemporaryDirectory();
final file = File("${output.path}/example.pdf");
await file.writeAsBytes(await pdf.save());
}
When i'm calling the exportPdf() function by clicking a button, i'm getting the following error.
Uncaught (in promise) Error: MissingPluginException(No implementation
found for method getTemporaryDirectory on channel
plugins.flutter.io/path_provider)
I've been searching for this issue for a long time, but no solution has fixed this one.
Even though the path_provider package is imported, the getTemporaryDirectory() is never called, like it doesn't exist.
I need also to mention that i'm using universal_io, instead of dart:io, because i'm using flutter_web.
This error shows up for every function i'm calling and exists inside the path_provider/path_provider.dart file. I've also added inside path_provider/path_provider.dart a simple print function and i'm getting an error that the method is not found.
Thank you for your time.
Run these commands
flutter clean
flutter pub get
flutter run
Make sure after the first command, the build folder is removed.
I found out that this current package does not support file saving in web and it is suggested to use the printing plugin to print or share the file.
I am getting an error whilst using Firebase Cloud Functions when I try to call a callable function from Flutter.
flutter: caught generic exception
flutter: PlatformException(functionsError, Firebase function failed with exception., {message: NOT FOUND, code: NOT_FOUND})
Here is how I try to call the cloud function with using cloud_functions: ^0.4.2+3
import 'package:cloud_functions/cloud_functions.dart';
_check(String id) async {
HttpsCallable callable = CloudFunctions.instance
.getHttpsCallable(functionName: 'checkUserFavorites');
try {
final HttpsCallableResult result = await callable.call(
<String, dynamic>{
'id': id,
},
);
print(result.data);
} on CloudFunctionsException catch (e) {
print('caught firebase functions exception');
print(e.code);
print(e.message);
print(e.details);
} catch (e) {
print('caught generic exception');
print(e);
}
}
I have experienced similar issues, and with few days of debugging and experimenting I found the solution only after studying the source code of Cloud Functions Plugin for Flutter.
When you deploy Firebase Cloud function, you can choose any region of preference (closer to your application the better). For example
// using DigitalOcean spaces
exports.generateCloudImageUrl = functions
.region('europe-west3')
.https.onCall((reqData, context) => {
...
}
When you want to call this function from Flutter app, you must specify the region, otherwise all goes to us-central1 which is default. See example code on how to use a function deployed in a specific region
final HttpsCallable generateCloudImageUrl = new CloudFunctions(region: "europe-west3")
.getHttpsCallable(functionName: 'generateCloudImageUrl');
// NB! if you initialize with 'CloudFunctions.instance' then this uses 'us-central1' as default region!
see cloud_function source for init.
Update, as of recent release, you can initialize as below;
FirebaseFunctions.instanceFor(region: "europe-west3").httpsCallable(
"generateCloudImageUrl",
options:
HttpsCallableOptions(timeout: const Duration(seconds: 30)));
Cloud functions are supported in the regions that you are currently running them, according to the Cloud Functions Location Documentation, but not in all regions.
According to what you shared in the comments, I would say that there are 3 cenarios to your issue:
europe-west1: The function is probably out of date, since you are getting an unespected data format error, which suggest that it expects different data/format than your default function.
europe-west2: The function is not deployed in this region, this is hinted in the error message message: NOT FOUND.
Default Function (unknown region): This is the most recent version of the function, on a region different than europe-west1 and europe-west2, and it accepts the call
with the data in the format that you are sending.
NOTE: You can check which regions you currently have your cloud function deployed on the cloud functions dashboard, as you can see on the example image below:
Also, I suspect that the default region you using is us-central1, since according to the documentation:
By default, functions run in the us-central1 region
To fix your issue, I suggest that you redeploy your current version of the function to the europe-west regions that you intend to use.
There are three reasons this error mostly happens:
1. Call the correct function:
Make sure to call the correct function in its full name (visible when you start a local emulator). Espacially if you have additional exports of files in your index.js file make sure to call the export name as well.
Syntax: serverLocation-optionalExportParent-yourFunction
Example: us-central1-post_functions-updateShare
Note that the server location can also be configured in your instance
2. Emulator: Same WIFI
Make sure to be connected to the same wifi, when using the emulator. Otherwise, any call will end in unvailablity resulting in
Unhandled Exception: [firebase_functions/unavailable] UNAVAILABLE
3. Emulator: Correct host configuration
To connect to a physical device the host at all emulators at your firebase.json must be configured: Simply add "host": "0.0.0.0".
Now the host in flutter needs to be your ip-adress of the computer. More on that here
In my case, in addition to the regional issue, what really solved to me was to include the script below in index.html:
<script src="https://www.gstatic.com/firebasejs/8.10.1/firebase-functions.js"></script>
I am working on google places API with Flutter. I am working by referring the example. But I got errors for google places API classes as
Eg:
Undefined class 'GoogleMapsPlaces'.
Try changing the name to the name of an existing class, or creating a class with the name
I imported the flutter_google_places in my dart file as:
import 'package:flutter_google_places/flutter_google_places.dart'; But still I got the error for all classes.
Using flutter_google_places version 0.2.3.
GoogleMapPlaces is available on different library, not in flutter_google_places...
it's available on https://pub.dev/packages/google_maps_webservice
you can find another package for google place google_place
var googlePlace = GooglePlace("Your-Key");
var result = await googlePlace.autocomplete.get("1600 Amphitheatre");
You need to import
import 'package:google_maps_webservice/places.dart'; in your main.dart.