Dart Stream Not Cancelling - flutter

I have a class that contains a stream that listens for objects to be created.
class Conversation {
// variables for live query
late QueryBuilder<ParseObject> message_live_query_;
final LiveQuery live_query = LiveQuery(debug: true);
// variables for streams
final message_added_stream_controller = StreamController<ParseObject>();
// constructor that gets messages and starts livequery
Conversation(this.conversation_, this.receiving_user_) {
// init and active live query
message_live_query_ = QueryBuilder<ParseObject>(ParseObject('Message'));
message_live_query_.whereEqualTo('conversation', conversation_);
initLiveQuery();
}
// returns the stream controller to be listened to
Stream get messageAddedStream => message_added_stream_controller.stream;
// listens to live query and if a message is detected, the stream notifies the listeners
void initLiveQuery() async {
final subscription = await live_query.client.subscribe(message_live_query_);
subscription.on(LiveQueryEvent.create, (message) {
print('*** MESSAGE CREATED FOR CONVERSATION OBJECT $getObjectID');
print('$message');
// notify the stream and add to local list
if(message_added_stream_controller.hasListener) { /// check if there is a listener, if not, don't add the value
message_added_stream_controller.add(message);
}
latest_message_ = message;
messages.add(message);
});
}
}
In a view I start listening to the stream with a stream listener, and when the user hits the back button I call another function to cancel the stream listener.
class _DirectMessageState extends State<DirectMessage> {
// list that holds messages
late List<types.Message> chatapp_message_list;
// variables for listening for new messages
StreamSubscription<dynamic>? messageAddedStreamListener = null;
// starts listening to stream
void listenMessageCreationStream() async {
// calls the classes getter function and starts listening to the stream
messageAddedStreamListener = widget.local_conversation.messageAddedStream.listen((message) {
print("MESSAGE HAS BEEN CREATED");
print(message);
if (message['sending_user_info']['objectId'] != widget.local_user.getUserInfoObjectID) {
setState(() {
chatapp_message_list.insert(0,convertToChatAppMessageObj(
message, chatapp_sending_user, chatapp_receiving_user));
});
}
});
}
#override
void initState() {
super.initState();
listenMessageCreationStream();
}
// cancels the listener and sets it to null
Future<void> disposeListeners() async {
await messageAddedStreamListener?.cancel();
messageAddedStreamListener = null;
}
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: BODY_BACKGROUND_COLOR,
appBar: AppBar(
backgroundColor: HEADER_FOOTER_BACKGROUND_COLOR,
title: const Text(
"Direct Message",
style: TextStyle(
color: TEXT_COLOR,
fontSize: SECONDARY_PAGE_HEADER_SIZE,
),
),
centerTitle: true,
leading: IconButton(
icon: const Icon(Icons.arrow_back),
onPressed: () async {
await disposeListeners(); // WAIT TO CANCEL SUBSCRIPTION HERE
globals.GlobalVars().navigatorKey.currentState?.pop(newlyCreatedListing);
}),
),
body: ...,
);
}
}
However when I navigate to the prior page, and re-navigate back to the DirectMessage page I get the following error that the stream is already being listened to
E/flutter ( 9347): [ERROR:flutter/runtime/dart_vm_initializer.cc(41)] Unhandled Exception: Bad state: Stream has already been listened to.
E/flutter ( 9347): #0 _StreamController._subscribe (dart:async/stream_controller.dart:676:7)
E/flutter ( 9347): #1 _ControllerStream._createSubscription (dart:async/stream_controller.dart:827:19)
E/flutter ( 9347): #2 _StreamImpl.listen (dart:async/stream_impl.dart:471:9)
E/flutter ( 9347): #3 _DirectMessageState.listenMessageCreationStream (package:supply_my_degree/social/direct_message.dart:88:79)
E/flutter ( 9347): #4 _DirectMessageState.initState (package:supply_my_degree/social/direct_message.dart:107:5)
E/flutter ( 9347): #5 StatefulElement._firstBuild (package:flutter/src/widgets/framework.dart:5015:57)
E/flutter ( 9347): #6 ComponentElement.mount (package:flutter/src/widgets/framework.dart:4853:5)
E/flutter ( 9347): #7 Element.inflateWidget (package:flutter/src/widgets/framework.dart:3863:16)
E/flutter ( 9347): #8 Element.updateChild (package:flutter/src/widgets/framework.dart:3592:18)
E/flutter ( 9347): #9 SingleChildRenderObjectElement.mount (package:flutter/src/widgets/framework.dart:6300:14)
E/flutter ( 9347): #10 Element.inflateWidget (package:flutter/src/widgets/framework.dart:3863:16)
E/flutter ( 9347): #11 Element.updateChild (package:flutter/src/widgets/framework.dart:3592:18)
E/flutter ( 9347): #12 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:4904:16)
E/flutter ( 9347): #13 Element.rebuild (package:flutter/src/widgets/framework.dart:4604:5)
E/flutter ( 9347): #14 ComponentElement._firstBuild (package:flutter/src/widgets/framework.dart:4859:5)
E/flutter ( 9347): #15 ComponentElement.mount (package:flutter/src/widgets/framework.dart:4853:5)
I'm not understanding how the stream isn't being cancelled by calling the disposeListeners() function before I exit the screen.

Related

How to get firebase data back in simple array

I have two collections::
group
group users
The group users collection has documents ...
Each document has two fields
Group id
User id
The group collection has documents ...
Each document has two fields
Group manager id
Group name
Using the currently logged-in user, I want to do the following:
query the group users collection to get the groups id,
query the groups collection to get the groups name.
Pretty simple I think... BUT I CANT DO IT
This is the function that I am using:
printData() {
var arr = [];
groupUser.snapshots().listen((data) {
data.docs.forEach((element) {
print(element['Group id']);
arr.add(element['Group id']);
});
});
return arr.first;
}
I get the error below, but the print statement works:
The following StateError was thrown building TestView(dirty, state: _TestViewState#38814):
Bad state: No element
The relevant error-causing widget was
TestView
lib/views_and_widgets/navigator_view.dart:36
When the exception was thrown, this was the stack
#0 List.first (dart:core-patch/growable_array.dart:343:5)
#1 FirebaseCloudStorage.printData
package:ijob_clone_app/…/cloud/firebase_cloud_storage.dart:87
#2 _TestViewState.build
package:ijob_clone_app/views_and_widgets/test_view.dart:35
#3 StatefulElement.build
package:flutter/…/widgets/framework.dart:4992
#4 ComponentElement.performRebuild
package:flutter/…/widgets/framework.dart:4878
#5 StatefulElement.performRebuild
package:flutter/…/widgets/framework.dart:5050
#6 Element.rebuild
package:flutter/…/widgets/framework.dart:4604
#7 ComponentElement._firstBuild
package:flutter/…/widgets/framework.dart:4859
#8 StatefulElement._firstBuild
package:flutter/…/widgets/framework.dart:5041
#9 ComponentElement.mount
package:flutter/…/widgets/framework.dart:4853
... Normal element mounting (25 frames)
#34 Element.inflateWidget
package:flutter/…/widgets/framework.dart:3863
#35 MultiChildRenderObjectElement.inflateWidget
package:flutter/…/widgets/framework.dart:6435
#36 MultiChildRenderObjectElement.mount
package:flutter/…/widgets/framework.dart:6447
... Normal element mounting (113 frames)
#149 Element.inflateWidget
package:flutter/…/widgets/framework.dart:3863
#150 Element.updateChild
package:flutter/…/widgets/framework.dart:3586
#151 ComponentElement.performRebuild
package:flutter/…/widgets/framework.dart:4904
#152 StatefulElement.performRebuild
package:flutter/…/widgets/framework.dart:5050
#153 Element.rebuild
package:flutter/…/widgets/framework.dart:4604
#154 BuildOwner.buildScope
package:flutter/…/widgets/framework.dart:2667
#155 WidgetsBinding.drawFrame
package:flutter/…/widgets/binding.dart:882
#156 RendererBinding._handlePersistentFrameCallback
package:flutter/…/rendering/binding.dart:378
#157 SchedulerBinding._invokeFrameCallback
package:flutter/…/scheduler/binding.dart:1175
#158 SchedulerBinding.handleDrawFrame
package:flutter/…/scheduler/binding.dart:1104
#159 SchedulerBinding._handleDrawFrame
package:flutter/…/scheduler/binding.dart:1015
#160 _invoke (dart:ui/hooks.dart:148:13)
#161 PlatformDispatcher._drawFrame (dart:ui/platform_dispatcher.dart:318:5)
This is the screen I am printing from:
class TestView extends StatefulWidget {
const TestView({Key? key}) : super(key: key);
#override
_TestViewState createState() => _TestViewState();
}
class _TestViewState extends State<TestView> {
late final FirebaseCloudStorage _groupUsersService;
String get userId => AuthService.firebase().currentUser!.id; // this is how I get the current logged in users userId
#override
void initState() {
_groupUsersService = FirebaseCloudStorage();
super.initState();
}
#override
Widget build(BuildContext context) {
print(_groupUsersService.printData()); // THIS IS THE PRINT STATEMENT
return Scaffold(
appBar: AppBar(
title: const Text('All users in my group'),
// ignore: prefer_const_literals_to_create_immutables
actions: [
// ignore: prefer_const_constructors
IconButton(
onPressed: null,
icon: const Icon(Icons.add),
),
],
),
body: StreamBuilder(
stream: _groupUsersService.getAllUsersInMyGroup(userId: userId),
builder: (context, snapshot) {
switch (snapshot.connectionState) {
case ConnectionState.waiting:
case ConnectionState.active:
if (snapshot.hasData) {
final allUsers = snapshot.data as Iterable<CloudGroupUser>;
return GroupUserListView(
cloudUsers: allUsers,
// onDeleteJob: (job) async {
// await _groupUsersService.deleteJob(documentId: job.documentId);
// },
onTap: (job) {
Navigator.of(context).pushNamed(
newJobRoute,
arguments: job,
);
},
);
} else {
return const CircularProgressIndicator();
}
default:
return const CircularProgressIndicator();
}
},
),
);
}
}
i removed the print statment from the view for the info below ( it still dont work)
I even tried to make it async ::
printData() async {
var arr = [];
await groupUser.snapshots().listen((data) {
data.docs.forEach((element) {
//print(element['Group id']);
arr.add(element['Group id']);
});
});
print(arr.first);
}
Restarted application in 525ms.
D/EGL_emulation( 4267): app_time_stats: avg=763.88ms min=17.12ms max=2249.43ms count=3
E/flutter ( 4267): [ERROR:flutter/runtime/dart_vm_initializer.cc(41)] Unhandled Exception: Bad state: No element
E/flutter ( 4267): #0 List.first (dart:core-patch/growable_array.dart:343:5)
E/flutter ( 4267): #1 FirebaseCloudStorage.printData
package:ijob_clone_app/…/cloud/firebase_cloud_storage.dart:88
E/flutter ( 4267): <asynchronous suspension>
E/flutter ( 4267):
W/DynamiteModule( 4267): Local module descriptor class for com.google.android.gms.providerinstaller.dynamite not found.
I/DynamiteModule( 4267): Considering local module com.google.android.gms.providerinstaller.dynamite:0 and remote module com.google.android.gms.providerinstaller.dynamite:0
W/ProviderInstaller( 4267): Failed to load providerinstaller module: No acceptable module com.google.android.gms.providerinstaller.dynamite found. Local version is 0 and remote version is 0.
D/TrafficStats( 4267): tagSocket(141) with statsTag=0xffffffff, statsUid=-1
==============+======================
I tried the following as well and got this error
printData() async {
var arr = [];
await groupUser.snapshots().listen((data) {
data.docs.forEach((element) {
//print(element['Group id']);
arr.add(element.data()['Group id']);
});
});
print(arr.first);
}
the code on the view was changed to the following::
#override
Widget build(BuildContext context) {
_groupUsersService.printData();
this is the error I got
Restarted application in 558ms.
D/EGL_emulation( 4267): app_time_stats: avg=600.59ms min=20.48ms max=1754.64ms count=3
E/flutter ( 4267): [ERROR:flutter/runtime/dart_vm_initializer.cc(41)] Unhandled Exception: Bad state: No element
E/flutter ( 4267): #0 List.first (dart:core-patch/growable_array.dart:343:5)
E/flutter ( 4267): #1 FirebaseCloudStorage.printData
package:ijob_clone_app/…/cloud/firebase_cloud_storage.dart:98
E/flutter ( 4267): <asynchronous suspension>
E/flutter ( 4267):
W/DynamiteModule( 4267): Local module descriptor class for com.google.android.gms.providerinstaller.dynamite not found.
I/DynamiteModule( 4267): Considering local module com.google.android.gms.providerinstaller.dynamite:0 and remote module com.google.android.gms.providerinstaller.dynamite:0
W/ProviderInstaller( 4267): Failed to load providerinstaller module: No acceptable module com.google.android.gms.providerinstaller.dynamite found. Local version is 0 and remote version is 0.
D/TrafficStats( 4267): tagSocket(123) with statsTag=0xffffffff, statsUid=-1
W/System ( 4267): Ignoring header X-Firebase-Locale because its value was null.
D/TrafficStats( 4267): tagSocket(121) with statsTag=0xffffffff, statsUid=-1
D/FirebaseAuth( 4267): Notifying id token listeners about user ( U8EZAjrCWQRvll6CVmI6OpGZwcH3 ).
You should be using element.data()['Group id'] instead of element['Group id'].
Happy coding :)
.onSnapshot() is an asynchronous observer. It returns a generic object with connection. First check are data he requests exits, then assign it somewhere or don't use snapshot, use simple .get() method. Unfortunately, I cannot help you more because I'm not a swift/flutter programmer.
I was looking for something like this
Future getAllUsersInManagersGroup(String userId) async {
//* managersGroupId: group id to which manager belongs to
//* allGroupUsersDocs: all GroupUser docs
//* allUserGroups: all GroupUsers in a List form
//* usersInManagersGroup: all users in managers group
// assumption: manager can only be in one group
String? managersGroupId;
final allGroupUsersDocs = await groupUser.get();
final allUserGroups = allGroupUsersDocs.docs.map((e) => e.data()).toList();
for (var user in allUserGroups) {
if (user['User id'] == userId) {
managersGroupId = user['Group id'];
break;
}
}
if (managersGroupId == null) return null;
var usersInManagersGroup = [];
for (var user in allUserGroups) {
if (user['Group id'] == managersGroupId) {
usersInManagersGroup.add(user['User id']);
}
}
return usersInManagersGroup;
}

'instanceFactory != null': Object/factory with type UserController is not registered inside GetIt. (But it is)

I have a two apps project, I am using get_it to get the profile picture from firebase Storage
.
The problem is that in the first app the code is working perfectly and the sign in procedure finish up normally, but in this one I copied the code as it was and made the necessary changes (imports mostly) however getting the profile picture using get_it is interrupting the signing and the sign up procedure and returning this error in the console:
/flutter ( 4798): [ERROR:flutter/lib/ui/ui_dart_state.cc(198)] Unhandled Exception: 'package:get_it/get_it_impl.dart': Failed assertion: line 372 pos 7: 'instanceFactory != null': Object/factory with type UserController is not registered inside GetIt.
package:get_it/get_it_impl.dart:372
E/flutter ( 4798): (Did you accidentally do GetIt sl=GetIt.instance(); instead of GetIt sl=GetIt.instance;
E/flutter ( 4798): Did you forget to register it?)
E/flutter ( 4798): #0 _AssertionError._doThrowNew (dart:core-patch/errors_patch.dart:51:61)
E/flutter ( 4798): #1 _AssertionError._throwNew (dart:core-patch/errors_patch.dart:40:5)
E/flutter ( 4798): #2 _GetItImplementation._findFactoryByNameAndType
package:get_it/get_it_impl.dart:372
E/flutter ( 4798): #3 _GetItImplementation.get
package:get_it/get_it_impl.dart:393
E/flutter ( 4798): #4 _SignInPageState.build.<anonymous closure>
package:nhafeflek/…/authentication/sign_in.dart:193
E/flutter ( 4798): #5 _SignInPageState.build.<anonymous closure>
package:nhafeflek/…/authentication/sign_in.dart:190
E/flutter ( 4798): #6 _InkResponseState._handleTap
E/flutter ( 4798): #7 GestureRecognizer.invokeCallback
package:flutter/…/gestures/recognizer.dart:198
E/flutter ( 4798): #8 TapGestureRecognizer.handleTapUp
package:flutter/…/gestures/tap.dart:613
E/flutter ( 4798): #9 BaseTapGestureRecognizer._checkUp
package:flutter/…/gestures/tap.dart:298
E/flutter ( 4798): #10 BaseTapGestureRecognizer.handlePrimaryPointer
package:flutter/…/gestures/tap.dart:232
E/flutter ( 4798): #11 PrimaryPointerGestureRecognizer.handleEvent
package:flutter/…/gestures/recognizer.dart:563
E/flutter ( 4798): #12 PointerRouter._dispatch
package:flutter/…/gestures/pointer_router.dart:94
E/flutter ( 4798): #13 PointerRouter._dispatchEventToRoutes.<anonymous closure>
package:flutter/…/gestures/pointer_router.dart:139
E/flutter ( 4798): #14 _LinkedHashMapMixin.forEach (dart:collection-patch/compact_hash.dart:614:13)
E/flutter ( 4798): #15 PointerRouter._dispatchEventToRoutes
package:flutter/…/gestures/pointer_router.dart:137
E/flutter ( 4798): #16 PointerRouter.route
package:flutter/…/gestures/pointer_router.dart:123
E/flutter ( 4798): #17 GestureBinding.handleEvent
E/flutter ( 4798): #18 GestureBinding.dispatchEvent
package:flutter/…/gestures/binding.dart:425
E/flutter ( 4798): #19 RendererBinding.dispatchEvent
package:flutter/…/rendering/binding.dart:326
E/flutter ( 4798): #20 GestureBinding._handlePointerEventImmediately
package:flutter/…/gestures/binding.dart:380
E/flutter ( 4798): #21 GestureBinding.handlePointerEvent
package:flutter/…/gestures/binding.dart:344
E/flutter ( 4798): #22 GestureBinding._flushPointerEventQueue
package:flutter/…/gestures/binding.dart:302
E/flutter ( 4798): #23 GestureBinding._handlePointerDataPacket
package:flutter/…/gestures/binding.dart:285
E/flutter ( 4798): #24 _rootRunUnary (dart:async/zone.dart:1442:13)
E/flutter ( 4798): #25 _CustomZone.runUnary (dart:async/zone.dart:1335:19)
E/flutter ( 4798): #26 _CustomZone.runUnaryGuarded (dart:async/zone.dart:1244:7)
E/flutter ( 4798): #27 _invoke1 (dart:ui/hooks.dart:170:10)
E/flutter ( 4798): #28 PlatformDispatcher._dispatchPointerDataPacket (dart:ui/platform_dispatcher.dart:331:7)
E/flutter ( 4798): #29 _dispatchPointerDataPacket (dart:ui/hooks.dart:94:31)
and as I already said it is registered and already working in the other app and here is my code:
My locator.dart file
import 'package:get_it/get_it.dart';
import 'package:nhafeflek/services/auth.dart';
import 'package:nhafeflek/services/storage.dart';
import 'package:nhafeflek/services/userController.dart';
var locator = GetIt.instance;
Future<void> setupServices() async {
locator.registerSingleton<AuthService>(AuthService());
locator.registerSingleton<StorageService>(StorageService());
locator.registerLazySingleton<UserController>(() => UserController());
}
My UserController.dart file:
import 'dart:io';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:nhafeflek/models/user.dart';
import 'package:nhafeflek/services/auth.dart';
import 'package:nhafeflek/services/locator.dart';
import 'package:nhafeflek/services/storage.dart';
class UserController {
late Userr _currentUser;
final AuthService _authService = locator.get<AuthService>();
final FirebaseAuth _auth = FirebaseAuth.instance;
late Future init;
final StorageService _storageService = locator.get<StorageService>();
UserController() {
init = initUser();
}
Future<Userr> initUser() async {
_currentUser = await _authService.getUser();
return _currentUser;
}
Userr get currentUser => _currentUser;
Future<void> uploadProfilePicture(File image) async {
_currentUser.avatarUrl = await _storageService.uploadFile(image);
}
Userr? _userFromFirebaseUser(User? user) {
if (user != null) {
return Userr(uid: user.uid);
} else {
return null;
}
}
Future<String> getDownloadUrl() async {
return await _storageService
.getUserProfileImageDownloadUrl(FirebaseAuth.instance.currentUser!.uid);
}
Future signInWithEmailAndPassword(String email, String password) async {
_currentUser =
await _authService.signInWithEmailAndPassword(email, password);
_currentUser = Userr(
uid: FirebaseAuth.instance.currentUser!.uid,
avatarUrl: await getDownloadUrl());
try {
UserCredential result = await _auth.signInWithEmailAndPassword(
email: email, password: password);
User barber = result.user!;
return _userFromFirebaseUser(barber);
} catch (e) {
return null;
}
}
}
My SignIn button:
ElevatedButton(
onPressed: () async {
if (_formKey.currentState!.validate()) {
dynamic result = await locator
.get<UserController>()
.signInWithEmailAndPassword(email, password);
if (result == null) {
setState(() =>
error = 'Something went wrong... Please try again!');
}
}
},
style: ButtonStyle(
shadowColor:
MaterialStateProperty.all(const Color(0xff5680a7)),
backgroundColor:
MaterialStateProperty.all(const Color(0xff5680a7)),
padding: MaterialStateProperty.all(const EdgeInsets.symmetric(horizontal: 120, vertical: 15)),
shape: MaterialStateProperty.all<RoundedRectangleBorder>(RoundedRectangleBorder(
borderRadius: BorderRadius.circular(5),
side: const BorderSide(
color: Color(0xff5680a7), width: 3)))),
child: const Text(
'Sign In',
style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
)
)
If you need any other sample of the code don't hesitate for asking. I seek your help.

I am getting error like this Unhandled Exception: Looking up a deactivated widget's ancestor is unsafe

What I trying to do here is getting data from the 000webhost.com and passing that to my model class. That model class is being passed to the provider. Now when I try to display the information in my screen i am getting error.
In this case i have a model class called StudentData.
class StudentData {
final String rollNumber;
final String firstName;
final String lastName;
StudentData({
this.rollNumber,
this.firstName,
this.lastName,
});
}
Here I am fetching data using http package from internet.
And passing the decoded data to the StudentData class and passing that to my data_provider
import 'package:http/http.dart' as http;
void getStudentData(String currentEmail, BuildContext context) async {
final _url = 'https://aaa.000webhostapp.com/getStudentData.php';
final response = await http.post(_url, body: {'email': currentEmail});
var data = response.body;
final decodedData = jsonDecode(data);
final myRollNumber = decodedData['roll_number'];
final myFirstName = decodedData['first_name'];
final myLastName = decodedData['last_name'];
final myStudentData = StudentData(
rollNumber: myRollNumber, firstName: myFirstName, lastName: myLastName);
Provider.of<DataProvider>(context, listen: false)
.getMyStudentData(myStudentData);
}
Here is my DataProvider
class DataProvider extends ChangeNotifier {
StudentData myStudentData;
void getMyStudentData(StudentData studentData) {
myStudentData = studentData;
notifyListeners();
}
}
After that I have tried to fetch those information in my Screen
class StudentDashboard extends StatelessWidget {
#override
Widget build(BuildContext context) {
return SafeArea(
child: Scaffold(
body: Center(
child:
Text(Provider.of<DataProvider>(context).myStudentData.rollNumber),
),
),
);
}
}
Then the error be like
======== Exception caught by widgets library =======================================================
The following NoSuchMethodError was thrown building StudentDashboard(dirty, dependencies: [_InheritedProviderScope<DataProvider>]):
The getter 'rollNumber' was called on null.
Receiver: null
Tried calling: rollNumber
The relevant error-causing widget was:
StudentDashboard file:///D:/Other/App/Flutter/my_ecampus/lib/views/screens/auth_screens/login_screen.dart:62:53
When the exception was thrown, this was the stack:
#0 Object.noSuchMethod (dart:core-patch/object_patch.dart:51:5)
#1 StudentDashboard.build (package:my_ecampus/views/screens/main_screens/student_screens/student_dashboard.dart:38:69)
#2 StatelessElement.build (package:flutter/src/widgets/framework.dart:4701:28)
#3 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:4627:15)
#4 Element.rebuild (package:flutter/src/widgets/framework.dart:4343:5)
...
====================================================================================================
E/flutter ( 7682): [ERROR:flutter/lib/ui/ui_dart_state.cc(177)] Unhandled Exception: Looking up a deactivated widget's ancestor is unsafe.
E/flutter ( 7682): At this point the state of the widget's element tree is no longer stable.
E/flutter ( 7682): To safely refer to a widget's ancestor in its dispose() method, save a reference to the ancestor by calling dependOnInheritedWidgetOfExactType() in the widget's didChangeDependencies() method.
E/flutter ( 7682): #0 Element._debugCheckStateIsActiveForAncestorLookup.<anonymous closure> (package:flutter/src/widgets/framework.dart:3906:9)
E/flutter ( 7682): #1 Element._debugCheckStateIsActiveForAncestorLookup (package:flutter/src/widgets/framework.dart:3920:6)
E/flutter ( 7682): #2 Element.getElementForInheritedWidgetOfExactType (package:flutter/src/widgets/framework.dart:3986:12)
E/flutter ( 7682): #3 Provider._inheritedElementOf (package:provider/src/provider.dart:324:34)
E/flutter ( 7682): #4 Provider.of (package:provider/src/provider.dart:281:30)
E/flutter ( 7682): #5 getStudentData (package:my_ecampus/business_view/services/database/getData_database.dart:19:12)
E/flutter ( 7682): <asynchronous suspension>
E/flutter ( 7682): #6 LoginScreen._login (package:my_ecampus/views/screens/auth_screens/login_screen.dart:60:9)
E/flutter ( 7682): <asynchronous suspension>
E/flutter ( 7682): #7 LoginScreen.build.<anonymous closure>.<anonymous closure> (package:my_ecampus/views/screens/auth_screens/login_screen.dart:198:31)
E/flutter ( 7682): #8 _InkResponseState._handleTap (package:flutter/src/material/ink_well.dart:993:19)
E/flutter ( 7682): #9 _InkResponseState.build.<anonymous closure> (package:flutter/src/material/ink_well.dart:1111:38)
E/flutter ( 7682): #10 GestureRecognizer.invokeCallback (package:flutter/src/gestures/recognizer.dart:183:24)
E/flutter ( 7682): #11 TapGestureRecognizer.handleTapUp (package:flutter/src/gestures/tap.dart:598:11)
E/flutter ( 7682): #12 BaseTapGestureRecognizer._checkUp (package:flutter/src/gestures/tap.dart:287:5)
E/flutter ( 7682): #13 BaseTapGestureRecognizer.acceptGesture (package:flutter/src/gestures/tap.dart:259:7)
E/flutter ( 7682): #14 GestureArenaManager.sweep (package:flutter/src/gestures/arena.dart:157:27)
E/flutter ( 7682): #15 GestureBinding.handleEvent (package:flutter/src/gestures/binding.dart:362:20)
E/flutter ( 7682): #16 GestureBinding.dispatchEvent (package:flutter/src/gestures/binding.dart:338:22)
E/flutter ( 7682): #17 RendererBinding.dispatchEvent (package:flutter/src/rendering/binding.dart:267:11)
E/flutter ( 7682): #18 GestureBinding._handlePointerEvent (package:flutter/src/gestures/binding.dart:295:7)
E/flutter ( 7682): #19 GestureBinding._flushPointerEventQueue (package:flutter/src/gestures/binding.dart:240:7)
E/flutter ( 7682): #20 GestureBinding._handlePointerDataPacket (package:flutter/src/gestures/binding.dart:213:7)
E/flutter ( 7682): #21 _rootRunUnary (dart:async/zone.dart:1206:13)
E/flutter ( 7682): #22 _CustomZone.runUnary (dart:async/zone.dart:1100:19)
E/flutter ( 7682): #23 _CustomZone.runUnaryGuarded (dart:async/zone.dart:1005:7)
E/flutter ( 7682): #24 _invoke1 (dart:ui/hooks.dart:265:10)
E/flutter ( 7682): #25 _dispatchPointerDataPacket (dart:ui/hooks.dart:174:5)
E/flutter ( 7682):
This is my main class and i am using multiprovider here.
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MultiProvider(
providers: [
ChangeNotifierProvider<WidgetProvider>(
create: (context) => WidgetProvider()),
ChangeNotifierProvider<DataProvider>(
create: (context) => DataProvider()),
],
child: MaterialApp(
home: LoginScreen(),
),
);
}
}
This is where I call getStudentData function
void _login({String email, String password, BuildContext context}) async {
final loginResponse =
await loginDatabase(email: email, password: password, context: context);
if (loginResponse.isNotEmpty) {
final isStaff = email.contains(RegExp(r'.ce#srit.org$'));
if (isStaff == true) {
getStaffData(email, context);
Navigator.pushReplacement(
context, MaterialPageRoute(builder: (context) => StaffDashboard()));
} else {
getStudentData(email, context);//here is the getStudentData() function
Navigator.pushReplacement(context,
MaterialPageRoute(builder: (context) => StudentDashboard()));
}
} else {
print('Login Failed from loginDatabase(){}');
}
}
The HTTP request is sent to the provider listen: false because it can not listen. So that you can call the method. That's why I designed it from scratch for you. I hope you understand. It will probably work if you do it as I did.
import 'package:http/http.dart' as http;
Future<StudentData> _getStudentData(String currentEmail, BuildContext context)async {
final _url = 'https://aaa.000webhostapp.com/getStudentData.php';
final response = await http.post(_url, body: {'email': currentEmail});
var data = response.body;
if (data.isEmpty) return null;
final decodedData = jsonDecode(data);
final myRollNumber = decodedData['roll_number'];
final myFirstName = decodedData['first_name'];
final myLastName = decodedData['last_name'];
final myStudentData = StudentData(
rollNumber: myRollNumber, firstName: myFirstName, lastName: myLastName);
return MystudentData;
}
class DataProvider extends ChangeNotifier {
StudentData myStudentData;
void getMyStudentData(StudentData studentData) {
myStudentData = studentData;
notifyListeners();
}
}
Future getMyStudentDataAsync() async {
StudentData result = await _getStudentData();
getMyStudentData(result);
}
class StudentDashboard extends StatelessWidget {
#override
void initState() {
super.initState(); getRequest();
}
future getRequest()async{
Provider.of<DataProvider>(context, listen: false)
.getMyStudentDataAsync();
}
#override
Widget build(BuildContext context) {
DataProvider _dataProvider = Provider.of<DataProvider>(context);
return SafeArea(
child: Scaffold(
body: Center(
child:
Text( _dataProvider.myStudentData.rollNumber),
),
),
);
}
}

Unhandled Exception: Exception: Failed to create Register

the method name is createResgister so this is the method that returns a Future that contains a Response. ok and in there is TextEdittingController of each form i want post and the api i want to post it too
ok am having an error trying to post a register form to an apiKey code:
import 'dart:convert';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:logistics_app/models/registerApi.dart';
import 'package:logistics_app/ui/dashboard_view.dart';
import 'package:logistics_app/utils/validation.dart';
import 'package:http/http.dart' as http;
import '../ui/login_view.dart';
class UserOnboardingModel extends ChangeNotifier with ValidationMixin{
TextEditingController firstController = TextEditingController();
TextEditingController lastController = TextEditingController();
TextEditingController passwordController = TextEditingController();
TextEditingController emailController = TextEditingController();
TextEditingController phoneController = TextEditingController();
bool showPassword = true;
final formKey = GlobalKey<FormState>();
Future<RegisterModel> _futureRegister;
Future<RegisterModel> createRegister()async{
final http.Response response = await http.post(
"apiKey",
body: jsonEncode(<String, String>{
'firstName' : validateFirstName(firstController.text),
'lastName' : validateLastName(lastController.text),
'emailAddress' : validateEmail(emailController.text),
'phoneNumber' : validatePhoneNumber(phoneController.text),
'password' : validatePassword(passwordController.text)
})
);
if(response.statusCode == 201){
return RegisterModel.fromJson(json.decode(response.body));
}else{
throw Exception('Failed to create Register');
}
}
void passRegister(){
_futureRegister = createRegister();
}
void registerForm(){
FutureBuilder<RegisterModel>(
future: _futureRegister,
builder: (context, snapshot){
if(snapshot.hasData){
return Column(
children: [
Text(snapshot.data.firstName),
Text(snapshot.data.lastName),
Text(snapshot.data.emailAddress),
Text(snapshot.data.phoneNumber),
Text(snapshot.data.password)
],
);
}else if(snapshot.hasError){
return Text("${snapshot.error}");
}
return CircularProgressIndicator();
},
);
}
void togglePassword(){
showPassword = !showPassword;
notifyListeners();
}
void validateForm(){
formKey.currentState.validate();
}
void moveToLogin(context){
//go to login page
if(formKey.currentState.validate()){
Navigator.pushNamed(context, LogIn.LOG_IN_ROUTE);
}
else{
Fluttertoast.showToast(
msg: "Please Fill The Form",
toastLength: Toast.LENGTH_LONG,
gravity: ToastGravity.BOTTOM,
timeInSecForIosWeb: 5,
backgroundColor: Colors.black,
);
}
}
void moveToDashBoardView(context){
//go to login page
if(formKey.currentState.validate()){
Navigator.push(context, MaterialPageRoute(
builder: (context) => DashboardView()
));
}
else{
Fluttertoast.showToast(
msg: "Please Fill The Form",
toastLength: Toast.LENGTH_LONG,
gravity: ToastGravity.BOTTOM,
timeInSecForIosWeb: 5,
backgroundColor: Colors.black,
);
}
}
void moveToSignup(){
//go to sign up page
notifyListeners();
}
void moveToForgottenPassword(){
//go to forgotten password page
notifyListeners();
}
}
now this is the error am getting saying: Failed to create Register
E/flutter ( 7901): [ERROR:flutter/lib/ui/ui_dart_state.cc(166)] Unhandled Exception: Exception: Failed to create Register
E/flutter ( 7901): #0 UserOnboardingModel.createRegister (package:logistics_app/models/userOnboardingModel.dart:42:7)
E/flutter ( 7901): <asynchronous suspension>
E/flutter ( 7901): #1 UserOnboardingModel.passRegister (package:logistics_app/models/userOnboardingModel.dart:47:23)
E/flutter ( 7901): #2 _buildCircleAvatar.<anonymous closure>.<anonymous closure> (package:logistics_app/ui/sign_up_view.dart:241:18)
E/flutter ( 7901): #3 _InkResponseState._handleTap (package:flutter/src/material/ink_well.dart:992:19)
E/flutter ( 7901): #4 _InkResponseState.build.<anonymous closure> (package:flutter/src/material/ink_well.dart:1098:38)
E/flutter ( 7901): #5 GestureRecognizer.invokeCallback (package:flutter/src/gestures/recognizer.dart:184:24)
E/flutter ( 7901): #6 TapGestureRecognizer.handleTapUp (package:flutter/src/gestures/tap.dart:524:11)
E/flutter ( 7901): #7 BaseTapGestureRecognizer._checkUp (package:flutter/src/gestures/tap.dart:284:5)
E/flutter ( 7901): #8 BaseTapGestureRecognizer.acceptGesture (package:flutter/src/gestures/tap.dart:256:7)
E/flutter ( 7901): #9 GestureArenaManager.sweep (package:flutter/src/gestures/arena.dart:158:27)
E/flutter ( 7901): #10 GestureBinding.handleEvent (package:flutter/src/gestures/binding.dart:224:20)
E/flutter ( 7901): #11 GestureBinding.dispatchEvent (package:flutter/src/gestures/binding.dart:200:22)
E/flutter ( 7901): #12 GestureBinding._handlePointerEvent (package:flutter/src/gestures/binding.dart:158:7)
E/flutter ( 7901): #13 GestureBinding._flushPointerEventQueue (package:flutter/src/gestures/binding.dart:104:7)
E/flutter ( 7901): #14 GestureBinding._handlePointerDataPacket (package:flutter/src/gestures/binding.dart:88:7)
E/flutter ( 7901): #15 _rootRunUnary (dart:async/zone.dart:1206:13)
E/flutter ( 7901): #16 _CustomZone.runUnary (dart:async/zone.dart:1100:19)
E/flutter ( 7901): #17 _CustomZone.runUnaryGuarded (dart:async/zone.dart:1005:7)
E/flutter ( 7901): #18 _invoke1 (dart:ui/hooks.dart:267:10)
E/flutter ( 7901): #19 _dispatchPointerDataPacket (dart:ui/hooks.dart:176:5)
E/flutter ( 7901):

Problem with BLE module : Exception: Another scan is already in progress

I'm trying to make possible the following actions:
I run my app and when I press the "Connect" button I connect to my BLE module.
A second button allows me to disconnect from it.
The problem is that if I connect to the BLE module, and then press the disconnect button, it disconnect but I will no longer be able to connect to the BLE anymore (and I have to restart the app).
There is my code:
import 'dart:async';
import 'dart:convert' show utf8;
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_blue/flutter_blue.dart';
void main() {
SystemChrome.setPreferredOrientations([
DeviceOrientation.landscapeRight,
DeviceOrientation.landscapeLeft
]);
runApp(MainScreen());
}
class MainScreen extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'BLUETOOTH',
debugShowCheckedModeBanner: false,
home: Home(),
theme: ThemeData.dark(),
);
}
}
class Home extends StatefulWidget {
#override
_HomeState createState() => _HomeState();
}
class _HomeState extends State<Home> {
String connectionText = "";
final String SERVICE_UUID = "4fafc201-1fb5-459e-8fcc-c5c9c331914b";
final String CHARACTERISTIC_UUID = "beb5483e-36e1-4688-b7f5-ea07361b26a8";
final String TARGET_DEVICE_NAME = "MLT-BT05";
FlutterBlue flutterBlue = FlutterBlue.instance; // * Instance de FlutterBlue
StreamSubscription<ScanResult> scanSubScription; // * StreamSubscription
BluetoothDevice targetDevice; // * Device
BluetoothCharacteristic targetCharacteristic; // * Characteristiques
#override
void initState() {
super.initState();
// startScan();
}
startScan() {
setState(() {
connectionText = "Start Scanning";
});
scanSubScription = flutterBlue.scan().listen((scanResult) {
print(scanResult.device.name.toString()); // ! TEST
if (scanResult.device.name == TARGET_DEVICE_NAME) {
print('DEVICE found');
stopScan();
setState(() {
connectionText = "Found Target Device";
});
targetDevice = scanResult.device;
connectToDevice();
}
}, onDone: () => stopScan());
}
stopScan() {
scanSubScription?.cancel();
scanSubScription = null;
}
connectToDevice() async {
if (targetDevice == null) return;
setState(() {
connectionText = "Device Connecting";
});
await targetDevice.connect();
print('DEVICE CONNECTED');
setState(() {
connectionText = "Device Connected";
});
discoverServices();
}
disconnectFromDevice() {
if (targetDevice == null) return;
targetDevice.disconnect();
setState(() {
connectionText = "Device Disconnected";
});
}
discoverServices() async {
if (targetDevice == null) return;
List<BluetoothService> services = await targetDevice.discoverServices();
services.forEach((service) {
// do something with service
if (service.uuid.toString() == SERVICE_UUID) {
service.characteristics.forEach((characteristic) {
if (characteristic.uuid.toString() == CHARACTERISTIC_UUID) {
targetCharacteristic = characteristic;
writeData("Hi there, ESP32!!");
setState(() {
connectionText = "All Ready with ${targetDevice.name}";
});
}
});
}
});
}
writeData(String data) {
if (targetCharacteristic == null) return;
List<int> bytes = utf8.encode(data);
targetCharacteristic.write(bytes);
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(connectionText),
centerTitle: true,
),
body: Center(
child: Column(
children: <Widget>[
FlatButton(
child: Text("Connect"),
color: Colors.grey[700],
onPressed: () {
startScan();
},
),
FlatButton(
child: Text("Disconnect"),
color: Colors.grey[700],
onPressed: () {
disconnectFromDevice();
},
),
],
),
),
);
}
}
The error tells me that another scan is already in progress even though the scanSubScription is canceled and set to null once the device is connected.
The error:
I/flutter (13433): [TV] Samsung 7 Series (55)
I/flutter (13433): MLT-BT05
I/flutter (13433): DEVICE found
I/flutter (13433): DEVICE CONNECTED
E/flutter (13433): [ERROR:flutter/lib/ui/ui_dart_state.cc(157)] Unhandled Exception: Exception: Another scan is already in progress.
E/flutter (13433): #0 FlutterBlue.scan (package:flutter_blue/src/flutter_blue.dart:81:7)
E/flutter (13433): <asynchronous suspension>
E/flutter (13433): #1 _HomeState.startScan (package:bluetoothv8/main.dart:53:36)
E/flutter (13433): #2 _HomeState.build.<anonymous closure> (package:bluetoothv8/main.dart:140:17)
E/flutter (13433): #3 _InkResponseState._handleTap (package:flutter/src/material/ink_well.dart:706:14)
E/flutter (13433): #4 _InkResponseState.build.<anonymous closure> (package:flutter/src/material/ink_well.dart:789:36)
E/flutter (13433): #5 GestureRecognizer.invokeCallback (package:flutter/src/gestures/recognizer.dart:182:24)
E/flutter (13433): #6 TapGestureRecognizer.handleTapUp (package:flutter/src/gestures/tap.dart:486:11)
E/flutter (13433): #7 BaseTapGestureRecognizer._checkUp (package:flutter/src/gestures/tap.dart:264:5)
E/flutter (13433): #8 BaseTapGestureRecognizer.handlePrimaryPointer (package:flutter/src/gestures/tap.dart:199:7)
E/flutter (13433): #9 PrimaryPointerGestureRecognizer.handleEvent (package:flutter/src/gestures/recognizer.dart:467:9)
E/flutter (13433): #10 PointerRouter._dispatch (package:flutter/src/gestures/pointer_router.dart:76:12)
E/flutter (13433): #11 PointerRouter._dispatchEventToRoutes.<anonymous closure> (package:flutter/src/gestures/pointer_router.dart:117:9)
E/flutter (13433): #12 _LinkedHashMapMixin.forEach (dart:collection-patch/compact_hash.dart:379:8)
E/flutter (13433): #13 PointerRouter._dispatchEventToRoutes (package:flutter/src/gestures/pointer_router.dart:115:18)
E/flutter (13433): #14 PointerRouter.route (package:flutter/src/gestures/pointer_router.dart:101:7)
E/flutter (13433): #15 GestureBinding.handleEvent (package:flutter/src/gestures/binding.dart:218:19)
E/flutter (13433): #16 GestureBinding.dispatchEvent (package:flutter/src/gestures/binding.dart:198:22)
E/flutter (13433): #17 GestureBinding._handlePointerEvent (package:flutter/src/gestures/binding.dart:156:7)
E/flutter (13433): #18 GestureBinding._flushPointerEventQueue (package:flutter/src/gestures/binding.dart:102:7)
E/flutter (13433): #19 GestureBinding._handlePointerDataPacket (package:flutter/src/gestures/binding.dart:86:7)
E/flutter (13433): #20 _rootRunUnary (dart:async/zone.dart:1138:13)
E/flutter (13433): #21 _CustomZone.runUnary (dart:async/zone.dart:1031:19)
E/flutter (13433): #22 _CustomZone.runUnaryGuarded (dart:async/zone.dart:933:7)
E/flutter (13433): #23 _invoke1 (dart:ui/hooks.dart:273:10)
E/flutter (13433): #24 _dispatchPointerDataPacket (dart:ui/hooks.dart:182:5)
Instead of:
stopScan() {
scanSubScription?.cancel();
scanSubScription = null;
}
write:
stopScan() {
flutterBlue.stopScan();
scanSubScription?.cancel();
scanSubScription = null;
}
please use like this
bluetoothInstance.stopScan().then((value) {
scanSubscription.cancel();
scanBLE(); //if you need, you can start scan again
});