Skipped x frames! The application may be doing too much work on its main thread. What does this error signify and how to solve this? - flutter

I'm trying to do authentication with firbase in my Flutter app. Once the user is signed in and goes to the Authenticted screen, this error shows up.
I'm using google_signin plugin with simple logics.
bool isAuth = false;
//check if the user is signed in
#override
void initState() {
super.initState();
googleSignIn.onCurrentUserChanged.listen((account) {
handleSignIn(account);
}, onError: (err) {
print("Error signing in: $err");
});
//maintain the signin
googleSignIn.signInSilently(suppressErrors: false).then((account) {
handleSignIn(account);
}).catchError((err) {
print("Error signing in: $err");
});
}
handleSignIn(GoogleSignInAccount account) {
if (account != null) {
print('User signed in!: $account');
setState(() {
isAuth = true;
});
} else {
setState(() {
isAuth = false;
});
}
}
//sign in using google
login() {
googleSignIn.signIn();
}
logout() {
googleSignIn.signOut();
}
Widget buildAuthScreen() {
return Center(
child: RaisedButton(
child: Text("LogOut"),
onPressed: logout(),
),
);
}
then the unauth screen has basic login layout for signining in...

If you are not doing anything unnecessary in your main, you can just ignore it.
the number of skipped frames is dependent on:
The number of static and top-level variables that need initiation on startup.
Speed of the CPU that will be doing computational work, like parsing JSONs at startup.
Speed of the device storage for initiating databases and shared preferences.
Whether you're using a debug or release build of your app.
The speed of the network connection in case of needing some necessary data before the app starts up.
Whether you're using an emulator or a physical device.
The size of the widget tree in your home page.

This is something you can't control sometimes, I faced this situation where an old android phone showed it skipped 180 frames where as a new phone said it skipped 25.

Related

Flutter firebase auth login is not updating to home page

I am trying to update the home of MaterialApp widget depending on whether the user has sign up or not.
Below is the code inside the state of ``MaterialApp```
String? _userUid;
#override
void initState() {
FirebaseAuth.instance.authStateChanges().listen((user) {
//print('changed');
print(user?.uid);
updateUser(user?.uid);
});
super.initState();
}
void updateUser(String? USER_UID) {
setState(() {
_userUid = USER_UID;
});
}
Below is the code for the home property
home: _userUid == null ? const Onbaording2() : const HomeScreen(),
Somewhere inside the widget tree
final user = await _firebaseAuth.createUserWithEmailAndPassword(
email: email!,
password: password!,
);
After running the code above, there is a user created in firebase but the screen does not change.
Also the signOut works perfectly by signing me out when I use firebaseAuth.instance.signOut();
even if you change your variable it will not be redirected to the home screen because materialapp is only called when you first load or restart the app so rather than adding this condtion in home page or other way can be
#override
void initState() {
FirebaseAuth.instance.authStateChanges().listen((user) {
//print('changed');
print(user?.uid);
if(user == null){ navigate to onboarding }
else{ navigate to home page }
});
super.initState();
}

Flutter webview plugin onUrlChanged is not working

I am trying to use the web view plugin in the flutter with the following code. However, I am only receiving the first 2 debug messages to the console. Does anyone know why this is? Could someone be able to point me in the direction of the answer? I found out about putting the listener to initState but that didn't work either.
Any solutions?
Here is my code for the widget.
(Installing on android btw)
Widget webView() {
// OPEN WEBVIEW ACCORDING TO URL GIVEN
print("debug");
flutterWebviewPlugin.launch(instagram.url);
// LISTEN CHANGES
print("debug1");
flutterWebviewPlugin.onUrlChanged.listen((String url) async {
print("debug2");
// IF SUCCESS LOGIN
if (url.contains(instagram.redirectUri)) {
instagram.getAuthorizationCode(url);
instagram.getTokenAndUserID().then((isDone) {
if (isDone) {
instagram.getLongLivedToken().then((isDone) {
if(isDone){
prefs.setString('token', instagram.longLivedAccessToken);
instagram.getUserProfile().then((isDone){
if(isDone){
instagram.getAllMedias();
setState(() {
images = instagram.imageUrls;
});
}
});
}
});
}
});
}
print("Login successful");
// NOW WE CAN CLOSE THE WEBVIEW
flutterWebviewPlugin.close();
Navigator.pop(context);
});
return WebviewScaffold(
resizeToAvoidBottomInset: true,
url: instagram.url,
);
}

flutter: Update values state in separate class with stream instead of setState()?

Im currently building an app that gets data from a separate class.
When the list devices gets filled, it should add an container to a Scrolable list.
I already managed to do that part, but.. cause the state of the devices list won't update on change the ui won't add an container either. And I can't use set state in the separate class..
void initState() {
// TODO: implement initState
super.initState();
getDevices();
}
Future<void> getDevices() async {
setState(() async {
deviceLength = drs.devices.length;
await drs.allDevices(specificDevices: 'DRS');
});
}
set state only updates deviceLength on start, but won't continue.
The length of devices is defined by following stream in a separate class Bluetooth, that adds objects to the List devices :
Future<Stream<void>> _findSingleResult({searchFor: ''}) async {
_flutterBlue.scanResults.listen((results) async {
// Return found Devices
try {
print('Device Found ? $deviceFound');
print(results.last.device.name);
//Does found device equal searched Device?
if (results.last.device.name.contains(searchFor)) {
deviceFound = true;
devices.add(results.last.device);
print('Device found...');
await _flutterBlue.stopScan();
return;
}
_counter++;
} catch (e) {
print(e);
}
});
}
If anyone knows how to solve this Issue pls help :)

Flutter: Hot restart crashes the app but cold restart doesn't (because a recorder is already initialized)

I am using the flutter_sound package to record some audio and as soon as the app starts up I initialise a recorder.
When I hot restart the app another recorder is initialised and the app crashes because on iOS there can only be one recorder.
When I cold restart the app I don't run into this problem, probably because all the resources are freed.
How can I make sure that the code that releases the recorder is called whenever I hot restart the app?
This is the relevant code in the UI.
#override
Widget build(BuildContext context) {
return MultiProvider(
providers: [
ChangeNotifierProvider<RecorderService>(
create: (_) => RecorderService(),
),
],
child: MaterialApp(
home: ScreenToShow(),
),
);
}
And this is the relevant code in the Recorder Service class:
class RecorderService with ChangeNotifier {
Recording recording;
RecordingStatus status = RecordingStatus.uninitialized;
static const String RECORDING_FORMAT = ".aac";
static const String LISTENING_FORMAT = ".mp3";
static const Duration UPDATE_DURATION_OF_STREAM = Duration(milliseconds: 100);
RecorderService() {
_initialize();
}
/// Private properties
FlutterSoundRecorder _recorder;
Directory _tempDir;
FileConverterService _fileConverterService = FileConverterService();
/// This is the file path in which the [_recorder] writes its data. From the moment it gets assigned in [_initialize()] it stays fixed
String _pathToCurrentRecording;
/// This is the file path to which the [recording] will be saved to. It changes with every call of [_startWithoutReset()]
String _pathToSavedRecording;
/// This function can only be executed once per session else it crashes on iOS (because there is already an initialized recorder)
/// So when we hot restart the app this makes it crash
_initialize() async {
try {
/// The arguments for [openAudioSession] are explained here: https://github.com/dooboolab/flutter_sound/blob/master/doc/player.md#openaudiosession-and-closeaudiosession
_recorder = await FlutterSoundRecorder().openAudioSession(
focus: AudioFocus.requestFocusAndKeepOthers,
category: SessionCategory.playAndRecord,
mode: SessionMode.modeDefault,
audioFlags: outputToSpeaker);
await _recorder.setSubscriptionDuration(UPDATE_DURATION_OF_STREAM);
_tempDir = await getTemporaryDirectory();
_pathToSavedRecording =
"${_tempDir.path}/saved_recording$LISTENING_FORMAT";
status = RecordingStatus.initialized;
notifyListeners();
} catch (e) {
print("Recorder service could not be initialized because of error = $e");
}
}
#override
dispose() async {
try {
await _recorder?.closeAudioSession();
super.dispose();
} catch (e) {
print("Recorder service could not be disposed because of error = $e");
}
}
}
Are you properly closing the session. Read the documentation from here
I realized that this is a month past your initial post but I came across this problem today.
I've found that the fix is to not call the following within the initState() of the page:
_recorder = await FlutterSoundRecorder().openAudioSession(...)
Instead, I created the following:
Future<void> startAudioSession() async {recorderModule.openAudioSession(...);}
And called it at the beginning of the startRecorder function, and then used the closeAudioSession() in the stopRecorder function.

Flutter : AppLifecycleState not work if devices in locked screen

I use AppLifeycleState to detect Behaviour my app when the user using it. For detect my app not being used, i used
AppLifecycleState.paused
AppLifecycleState.inActive
AppLifecycleState.detached
Because i want detect if my App not being used for 1 second, i throw user to Confirmation Fingerprint (Like Whatsapp). Everything is fine i can detect if my app not being used if user press recent app, Home button and throw user to Confirmation Fingerprint if user comeback again.
But the problem is , When devices screen in locked up then it opened again , user not throwing to Confirmation Fingerprint.
I surely can see in console my app is AppLifecycleState.paused and AppLifecycleState.inActive, but strangely if I hot reload ctrl +s in my IDE my app throwing me to Confirmation Fingerprint.
Why can be like this ?
Working 1
Working 2
Not Working !
Already tested too in real Device (Redmi Note 4) , and still not working.
Source Code AppLifecycleState
#override
void didChangeAppLifecycleState(AppLifecycleState state) async {
setState(() => _appLifecycleState = state);
if (widget.userBox == null) {
print('Box User Null');
return;
} else {
if (widget.userModelHive.fingerPrint || widget.userModelHive.pinCode) {
if (_appLifecycleState != AppLifecycleState.resumed) {
//? Berarti Lifecylenya InActive , Paused , Detached , Maka Simpan Waktu Keluarnya
final actionBox = await repository.changeDateExit(
userModelHive: UserModelHive()
..id = widget.userModelHive.id
..giverName = widget.userModelHive.giverName
..pinCode = widget.userModelHive.pinCode
..fingerPrint = widget.userModelHive.fingerPrint
..darkMode = widget.userModelHive.darkMode
..tokenExpiry = true
..durationToken = widget.userModelHive.durationToken
..dateExit = DateTime.now()
.add(Duration(seconds: widget.userModelHive.durationToken)),
);
print(state);
return actionBox;
} else {
print('Resumed Lifecycle');
}
}
}
if (mounted) {
setState(() {});
}
super.didChangeAppLifecycleState(state);
}