Tried to get location before initializing timezone database - flutter

I am trying to schedule a notification:but I got this error:
Unhandled Exception: Tried to get location before initializing timezone database
Although I initialized the Timezone in the init function:
tz.initializeTimeZones();
schedule code:
Future<void> scheduleNotifications(String title,int yy,int mm,int dd,int hh,int ii) async {
final loc_egypt = tz.getLocation('Africa/Cairo');
final tz.TZDateTime now = tz.TZDateTime.now(loc_egypt);
var schedule_30before=tz.TZDateTime(loc_egypt,yy,mm,dd,hh,ii).subtract(Duration(minutes: 30));
await flutterLocalNotificationsPlugin.zonedSchedule(
0,
title,
"The Webinar will start after 30 minutes",
schedule_30before,
NotificationDetails(android: _androidNotificationDetails),
androidAllowWhileIdle: true,
uiLocalNotificationDateInterpretation:
UILocalNotificationDateInterpretation.absoluteTime);
}

In my case the problem was with invalid assets. I am working on a Flutter Web project, so I was doing:
import 'package:timezone/browser.dart' as tz;
void main() async {
await tz.initializeTimeZone();
// other stuff
}
After digging into the source code of timezone package, I discovered that it is initialising using a *.tzf file, which I wasn't including in my project's assets (rookie's mistake). So I edited my pubspec.yaml like this:
flutter:
assets:
- packages/timezone/data/latest.tzf
# - packages/timezone/data/latest_all.tzf <- for all the db variants
# - packages/timezone/data/latest_10y.tzf <- for 10y db variant
But there was still one more thing to do. As it turns out tz.initializeTimeZone() assumes that a default path is packages/timezone/data/latest.tzf BUT my Flutter Web project was putting all the assets in assets catalogue, so the actual path was assets/packages/timezone/data/latest.tzf and I just had to pass it as an argument to tz.initializeTimeZone('assets/packages/timezone/data/$dbVariant'). Of course you need to replace $dbVariant with the variant of your choice, the one that you included in your assets.
TL;DR
Include a timezone database in assets:
flutter:
assets:
- packages/timezone/data/latest.tzf
Initialise timezone with a full path to assets:
import 'package:timezone/browser.dart' as tz;
void main() async {
await tz.initializeTimeZone('assets/packages/timezone/data/latest.tzf');
// other stuff
}

You need to import the following packages:
import 'package:timezone/data/latest.dart' as tzl;
import 'package:timezone/standalone.dart' as tz;
Then, you can call for example something like:
ElevatedButton(
onPressed: ()async {
await scheduleNotifications("title", 2022, 9, 1, 1, 47);
},
child: Text("Notify Me!"))
Given you put tzl.initializeTimeZones(); in your initState().
Your issue is in using initializeTimeZones() of a package different than "package:timezone/data/latest.dart"

In the main() method of your app, verify your imports and call the init method
//Pick one of the three following imports :
//If you just want the latest
import 'package:timezone/data/latest.dart' as tz;
//If you use the 10y db variant
import 'package:timezone/data/latest_10y.dart' as tz;
//If you want to import all the db variants
import 'package:timezone/data/latest_all.dart' as tz;
void main() {
tz.initializeTimeZones();
}

In my case I created a future method and initialized it in the main() function of the main.dart file. This is my code:
import 'package:timezone/browser.dart' as tz;
Future<void> main() async {
initTimeZone();
// add other setup here
}
void initTimeZone(){
tz.initializeTimeZones();
}
Hope this helps!

Related

Flutter file word readable

I want to write a file with flutter, that has got the same function as WORLD_READABLE in android. So i want tha this file can be read by all the applications.
More clear: i have an app A that write hello.txt i want that another app B can read this file. How i should set my file? There is a parameter of some function in the package path_provider?
I seen the package path_provider and File class, but i didn't find something.
I have already tried by access direct to file from app B, but is not world readable.
Something like this should work and make sure you use the latest path_provider dependency. getExternalStorageDirectory() does the trick!
//Write file from App 1
import 'dart:io';
import 'package:path_provider/path_provider.dart';
Future<void> writeToFile(String data) async {
final directory = await getExternalStorageDirectory();
final file = File('${directory.path}/hello.txt');
await file.writeAsString(data);
}
//Read the written file from App 2
import 'dart:io';
import 'package:path_provider/path_provider.dart';
Future<String> readFromFile() async {
final directory = await getExternalStorageDirectory();
final file = File('${directory.path}/hello.txt');
return file.readAsString();
}

Why can I not change from XFile to File?

I wish to display image taken from the Camera.
My imports are -
import 'dart:html';
import 'dart:io';
import 'package:file/file.dart';
import 'package:flutter/material.dart';
import 'package:image_picker/image_picker.dart';
The code block with the issue
class _CollectdataState extends State<Collectdata> {
XFile imageFile;
_getFromCamera() async {
XFile? pickedFile = await ImagePicker().pickImage(
source: ImageSource.camera,
maxWidth: 1800,
maxHeight: 1800,
);
if (pickedFile != null) {
File imageFile = File(pickedFile.path);
}
}
The error here was
1.File needs 2 parameters- I am unsure on what the second parameter is.
Then I changed something around idr what exactly but the imports if I remember correctly and this was the new error-
File is not a function
I need to change it to a File inorder to upload on Firebase and show the picture using image.file()
Any help is highly appreciated!
Please remove
import 'dart:html';
If this package isn't used.
Both html and dart:io provide File. The error that you mentioned was for File from html.

Cannot upload files to Firebase Storage using Flutter in Debug mode

Hi I'm having trouble testing uploading files to Firebase Storage with Flutter using an emulator in Android Studio. I keep getting this error even though I followed the documentation: https://firebase.google.com/docs/app-check/flutter/default-providers. I also followed the one for debug mode: https://firebase.google.com/docs/app-check/flutter/debug-provider.
Error getting App Check token; using placeholder token instead. Error:
com.google.firebase.FirebaseException: 7:
Here is my MainActivity.kt
import android.os.Bundle
import io.flutter.embedding.android.FlutterActivity
import com.google.firebase.appcheck.FirebaseAppCheck
import com.google.firebase.FirebaseApp
import com.google.firebase.appcheck.debug.DebugAppCheckProviderFactory
class MainActivity: FlutterActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
FirebaseApp.initializeApp(this)
val firebaseAppCheck = FirebaseAppCheck.getInstance()
firebaseAppCheck.installAppCheckProviderFactory(
DebugAppCheckProviderFactory.getInstance()
)
super.onCreate(savedInstanceState)
}
}
main.dart
void main() async {
WidgetsFlutterBinding.ensureInitialized();
if (Firebase.apps.isEmpty) {
await Firebase.initializeApp(
name: 'XXX',
options: DefaultFirebaseOptions.currentPlatform,
);
await FirebaseAppCheck.instance.activate(
webRecaptchaSiteKey: 'recaptcha-v3-site-key',
);
}
runApp(const MyApp());
}
I've read a lot of answers to this question but none work. I expect to see this line in my logs but I don't see it
D DebugAppCheckProvider: Enter this debug secret into the allow list
in the Firebase Console for your project:
123a4567-b89c-12d3-e456-789012345678
Please help. Thank you!

Flutter tests - Having two Integration tests in a same group ()

I'm trying to run two tests in a same group in one test file.
If I split them into two separate test files, they are working fine.
But if I add them in a group, the 2nd test fail with the error saying "TypeAdapter is already registered for the given id".
My app uses HiveDB and it sets up Hive boxes in the main.dart before launching the App. I understand that the 2nd test is also trying the same and fails because the setup is already done.
I followed this doc to setup and write integration tests.
Most of the youtube tutorials, medium articles, and other online resources explain so well on how to run one single test in a test file and they're outdated. I never found a resource having two tests in the same file yet.
Here's my main.dart
Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp();
await HiveDB.setup();
runApp(App());
}
test_driver/integration_test.dart
import 'package:integration_test/integration_test_driver.dart';
Future<void> main() => integrationDriver();
test/app_test.dart
import 'package:flutter_test/flutter_test.dart';
import 'package:integration_test/integration_test.dart';
import 'package:integrationtestdemo/main.dart' as app;
void main() {
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
group('Home screen tests', () {
tearDown(() async {
print("TearDown() -- called");
await HiveDB.close();
});
testWidgets('Scenario # - loreum ipsum ...', (tester) async {
// ARRANGE
await app.main();
await tester.pumpAndSettle();
// ACT
// ASSERT
expect(1 + 3, 4);
});
testWidgets('Scenario #2', (tester) async {
// ARRANGE
await app.main();
await tester.pumpAndSettle();
// ACT
// ASSERT
expect(2 + 2, 4);
});
});
}
The command I use to execute tests:
flutter drive --driver=.\test_driver\integration_test.dart --target=.\test\app_test.dart
Error I get:
══╡ EXCEPTION CAUGHT BY FLUTTER TEST FRAMEWORK ╞═════════════════
The following HiveError was thrown running a test:
There is already a TypeAdapter for typeId 1.
When the exception was thrown, this was the stack:
#0 TypeRegistryImpl.registerAdapter (package:hive/src/registry/type_registry_impl.dart:104:11)
#1 HiveDB.setup (package:occasionly/src/services/hive_db.dart:80:10)
<asynchronous suspension>
Could someone please help me here? I'm stuck on this for a long time and couldn't figure out a way to isolate the state between tests?
I have found a dirty trick to solve "TypeAdapter is already registered for the given id" this error
try to put it like this, and the error will not appear anymore
Hive.registerAdapter(YourAdapter(), override: true);
But I have no idea what is the possible impact could this argument do
I also faced the same issue, but I found a workaround by referring to this ERROR in flutter: widget_test.dart cannot detect MyApp(), you could try it.
testWidgets('Scenario #1', (tester) async {
// ARRANGE
await app.main();
...
});
testWidgets('Scenario #2', (tester) async {
// ARRANGE
await tester.pumpWidget(MyApp());
});

Save a memory image (such as Uint8list) as image file in flutter

I have some Uint8lists and I want to save them as jpg files.
Can anyone help?
By 'storage', do you mean write to a file? You don't really need "flutter" to do this. Just use the libraries provided by dart. Here is an example of downloading my gravatar which you can get as Uin8List and then saving it to a file.
import 'dart:io';
import 'dart:typed_data';
import 'package:http/http.dart' as http;
void main() {
http.get('https://www.gravatar.com/avatar/e944138e1114aefe4b08848a46465589').then((response) {
Uint8List bodyBytes = response.bodyBytes;
File('my_image.jpg').writeAsBytes(bodyBytes);
});
}
Here is a simple and short solution of your problem. Use this line in your code as I did:
"SettableMetadata(contentType: "image/jpeg"),"
Code:
if (kIsWeb) {
await ref.putData(
await imageFile.readAsBytes(),
SettableMetadata(contentType: "image/jpeg"),
);
url = await ref.getDownloadURL();
}