How to fix MissingPluginException on Agora video call? - flutter

I'm building an App which can make Video calls, I'm using Agora SDK for the feature. I'm having a problem when I want to run the app on my device. Naturally it would ask for Camera and Microphone permission but it doesn't ask me and the video call feature won't start. Here's some of my code:
The Function that gives me the error
Future<void> onJoin() async {
// update input validation
setState(() {
_channelController.text.isEmpty
? _validateError = true
: _validateError = false;
});
if (_channelController.text.isNotEmpty) {
// await for camera and mic permissions before pushing video page
await _handleCameraAndMic(); // doesn't asks for any permissions so the video call won't start
//await _permissions();
// push video page with given channel name
await Navigator.push(
context,
MaterialPageRoute(
builder: (context) => CallPage(
channelName: _channelController.text,
),
),
);
}
}
Future<void> _handleCameraAndMic() async {
await PermissionHandler().requestPermissions(
[PermissionGroup.camera, PermissionGroup.microphone],
);
}
The Exception I'm getting
Unhandled Exception: MissingPluginException(No implementation found
for method requestPermissions on channel
flutter.baseflow.com/permissions/methods)
I'm using this as a reference for bulding the feature
I'm not sure where did I do wrong because I'm very new to flutter development. Any help would be appreciated and if you need more code I will provide it to you, just feel free to ask. Thank you.

There is an open issue on their repo, see this.
Probably the plugin is buggy, so you may try some other plugin.

Related

MissingpluginException(No implementation found for method getApplicationDocementsDirectory on channel plugins.flutter.io/path_provider)

Hello guys this program consists of two pages named student list and studentdetail it don't make any error in the analyzer but in emulator when I open the first page that display list of students and tap on any student and go to the student detail and wanting to delete , update or goback to the fist page it says MissingpluginException(No implementation found for method getApplicationDocementsDirectory on channel plugins.flutter.io/path_provider)
where is the error
is the error in this code in the studentlist page
void navigateToStudent(Student student, String appTitle) async {
bool result =
await Navigator.push(context, MaterialPageRoute(builder: (context) {
return StudentDetail(student, appTitle);
}));
if (result) {
updateListView();
}
}
or the error in this code in studentdetail page
void goback() {
Navigator.pop(context, true);
}
there is the entire project in this link
https://github.com/abdelrahman992-cpu/studentfinal
stop the debugging proses and start again don't just hot reload it won't work, because some package need to rerun the app don't forget to flutter clean too if it still not working

Rebuild app or delete cache when redirect to home page Flutter

I have an app where when I logout with Firebase Auth, user's datas are still there, and I need to Hot restart the app to totally remove them.
I didn’t find a way to improve the signout method, so I want to try to rebuild app when user logout, or maybe delete the cache so user’s datas will no longer exist in app.
I have done some research but I can’t find any solution that can help me.
EDIT : Here's how I logout
Future<void> signOut() async {
await FirebaseAuth.instance
.signOut()
.then((value) => print('Sign Out'))
.onError((error, stackTrace) => print('Error in signed out'));
}
IconButton(
onPressed: () async {
await signOut();
Navigator.of(context, rootNavigator: true)
.pushAndRemoveUntil(
MaterialPageRoute(
builder: (BuildContext context) {
return const OnBoardingPage();
},
),
(_) => false,
);
},
icon: const Icon(Icons.logout))
I know that user's data are still there because I can display user.email in my onBoardingPage (where technically no data can be there because I logout previously).
Here a preview of my onBoardingPage :
After that, if I want to connect with another account, I will be connected to the previous user's session. The same if I want to create a new account, all new user's data will be into the previous connected user. To fix this problem, in development mode, I need to hot restart the app.
It seems like the user is not totally logout.

Getting null argument while routing through firebase push notifications flutter

I am trying to route to a certain screen with some argument when clicked on push notifications. So far it is working fine when app is in foreground or in background but open. But when the app is terminated it is routing to the correct screen but there is some issue with the argument, it is null.
const payload = admin.messaging.MessagingPayload = {
data : {
'type' : 'msg',
'route' : 'chat-screen',
'argument' : sentby,
},
notification : {
title : senderData.user_name,
body: original.message,
image: notificationIcon,
android_channel_id : "Finiso",
channel_id : "Finiso",
clickAction : 'FLUTTER_NOTIFICATION_CLICK',
}
}
This is the code for the notification which I am triggering through cloud functions.
Future<void> backgroundHandler(RemoteMessage message) async {
await Firebase.initializeApp();
print(message.data.toString());
print(message.notification.title);
}
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp();
FirebaseMessaging.onBackgroundMessage(backgroundHandler);
added this in main.dart
FirebaseMessaging.instance.getInitialMessage().then((message) async {
if (message != null) {
print(message.data);
routeNotification(message);
}
});
listening to messages and on app open trigger.
void routeNotification(RemoteMessage message) {
final routeName = message.data['route'];
if (routeName == ActivityFeed.routeName) {
Navigator.of(context).pushNamed(ActivityFeed.routeName);
} else {
if (message.data['type'] == 'msg') {
Navigator.pushNamed(
context,
message.data['route'],
arguments: message.data['argument'],
);
}
}
}
This is the routing function I used above
Image showing console logs
It is printing the first two lines from main.dart and "null" is the argument I am trying to get.
Can anyone help me on this. I have no idea what's going on.
Thank you in advance.
I have an answer but I'm not positive on the reason why this is happening yet. Let's collaborate on this.
First of all, I think the routing is happening automatically for you. In all other scenarios except the terminal state, you are pushing the route and handling adding the arguments. In the terminal state, the app is ignoring your initialRoute and using the route from your push notification.
Usually when you setup MaterialApp your initialRoute is used:
MaterialRoute(
initialRoute: '/whatever_you_put_here'
...
)
It seems that WidgetsBinding.instance.platformDispatcher.defaultRouteName (source) is being set within the flutter code and this is causing your default route to be this route instead of whatever you are passing to MaterialApp.
Reading the flutter documentation, it looks like this property is only set when someone calls FlutterView.setInitialRoute from Android.
That is the answer to your question.
--
I don't know what is calling FlutterView.setInitialRoute. A search of FlutterFire code seems to show no instances.

Problems with camera in flutter app (The selected imageFormatGroup is not supported by > Android. Defaulting to yuv420)

I have problems with integration of a photography function in my app.
I get asked if I permit the access to the camera, but after that nothing happens exept this errror:
W/Camera (26849): The selected imageFormatGroup is not supported by
Android. Defaulting to yuv420
I/CameraManagerGlobal(26849): Camera 0 facing CAMERA_FACING_BACK state
now CAMERA_STATE_OPEN for client...
This is my code:
class FaultReporting extends StatefulWidget {
#override
_FaultReportingState createState()=> _FaultReportingState();
}
class _FaultReportingState extends State<FaultReporting>{
bool isReady=false;
List<CameraDescription> cameras;
CameraController camController;
#override
void initState() {
super.initState();
setupCameras();
}
Future<void> setupCameras() async {
try {
cameras = await availableCameras();
camController = new CameraController(cameras[0], ResolutionPreset.medium);
await camController.initialize();
} on CameraException catch (_) {
setState(() {
isReady = false;
});
}
setState(() {
isReady = true;
});
}
...
child: ElevatedButton(
onPressed: (){
if(!isReady && !camController.value.isInitialized)
{
return Container();
}
return AspectRatio(
aspectRatio: camController.value.aspectRatio,
child: CameraPreview(camController),
);
},
...
I had the exact same error when I used the camera on flutter. The message is just informing you that the imageFormatGroup parameter must be ImageFormatGroup.yuv420.
So try this:
camController = new CameraController(
cameras[0],
ResolutionPreset.medium,
imageFormatGroup: ImageFormatGroup.yuv420,
);
I had the same issue. However, the abovementioned solution (adding imageFormatGroup: ImageFormatGroup.yuv420) did not solve the problem.
I found out what was the real problem. Turns out Flutter Navigation requires pushed routes to be popped before another one pushed into navigator.
Otherwise, it will cause big issues with all camera using packages (CameraController from camera, QRViewController? controller from qr_code_scanner, MobileScannerController cameraController from mobile_scanner all affected) using packages (Both Android and iOS), specially if you use your own custom internal navigation without using Flutter Navigator.
Because, that way you use Navigator partially and in some situations you push several different routes without popping them or even pushing same route several times.
The camera will come either black or keep loading forever. Only thing will solve the issue is to kill/force stop the app and open again as it clears Flutter Navigator.
In Android you will see this error: "MessageQueue: java.lang.IllegalStateException: Handler sending message to a Handler on a dead thread"
In iOS you will see this: "The selected imageFormatGroup is not supported by iOS. Defaulting to brga8888"
Another related error from mobile_scanner package: flutter: MobileScanner: Called start() while already started!
Realted error from qr_code_scanner package: Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Scan rect cannot be set when not (yet) scanning. You may want to set it within didStartScanningBlock.
Here is the solution which may help you to prevent it. What we need to do is to make sure that when we push new route to the Navigator we are clearing other previously pushed routes from it:
For undefined routes:
Navigator.of(context).pushAndRemoveUntil(
MaterialPageRoute(
builder: (context) => YourPage()),
(Route<dynamic> route) => false);
For defined routes:
Navigator.of(context)
.pushNamedAndRemoveUntil('/yourdefinedroute', (Route<dynamic> route) => false);

Firebase Cloud Messaging onLaunch callback

My app structure is a little bit mess, but I have to add this patch first and then I'll restructure the entire logic. The thing is I first check if there's a firebase user, then if there is one I use StreamBuilder to get the current user profile from Firestore, then I have the _firebaseMessaging.configure method because onLaunch and onResume I use this callback:
void _navigateToGestorResevas(Map<String, dynamic> message, User currentUser) {
Navigator.push(context,
MaterialPageRoute(builder: (context) =>
GestorScreen(user: currentUser)));
}
Because I need to send the User to this screen where he fetch the message from firebase.
onResume this works fine, but onLaunch it goes to the screen and fetch the data but there are like 20 seconds where there are some kind of glitch. It switch like 20-30 times between two states where I have and no have snapshot data in this _initState func:
final snapshot = await _dbRef.child('mensajes').child(widget.user.id).once();
if (snapshot.value != null) {
setState(() {
hayMensajes = true;
});
final data = snapshot.value;
for (var entry in data.entries) {
Message message = Message.fromJson(entry.value);
setState(() {
message.add(message);
});
}
} else {
setState(() {
hayMensajes = false;
});
}
Anyone have an idea what am I doing wrong?
If I am not mistaken, there are some active issues about FCM onLaunch callback with flutter. Some of them are still not fixed. One of the problems most people had to face was that onLaunch callback being called multiple times. I don't know why it happened, but as in your case, you can possibly get rid of the issue by some temporary fixes.
If the same screen is getting pushed over and over again, and glitching, you can pop the stack until it reaches the one you meant to open and set a condition to push navigator only if the new route is different from the old one. Using the named routes,
Navigator.popUntil(context, ModalRoute.withName(routeName));
if (ModalRoute.of(context).settings.name != routeName) {
Navigator.pushNamed(context, routeName);
}
I am not sure if that was the problem you asked, but I hope at least my answer helps somehow.