ZEGOCLOUD / zego_uikit_prebuilt_call_flutter

MIT License
16 stars 13 forks source link

The application does not go to the call (error: 'pageManager != null': pageManager is null) #41

Closed yokawaiik closed 4 months ago

yokawaiik commented 4 months ago

Hello!

I came across a problem for which I couldn't find a solution anywhere. I connected the package based on the information described in the documentation.

I would like to receive your help. Thank you in advance.

Environment

Technology Version
Flutter version 3.19.5
Plugin version zego_uikit_prebuilt_call: 4.9.0, zego_uikit_signaling_plugin: 2.7.6
Android version API 34
iOS version Not tested
macOS version Not tested
Xcode version Not tested
Google Chrome version Not tested

Device information:

I tried package on: real device pixel 7 with api 34; emulator pixel with api 34.

Description

Expected behavior: Opening the call screen on the device; request an incoming call on another device.

Current behavior: Nothing happens in the UI. The log contains the following error:


'package:zego_uikit_prebuilt_call/src/invitation/internal/internal_instance.dart': Failed assertion: line 21 pos 12: '_pageManager != null': pageManager is null, plugins call ZegoUIKitPrebuiltCallInvitationService().init(...) when user login

Steps to reproduce

  1. Wrote a service for calls (just divided into modules).

This service includes the implementation of interceptors for different events from the package side and some description of the custom UI.

videocalls_service.dart

```dart import 'package:app_name/custom_code/custom_lib/features/videocalls/src/actions/on_call_end_action.dart'; import 'package:app_name/custom_code/custom_lib/features/videocalls/src/actions/on_outgoing_call_declined_action.dart'; import 'package:app_name/custom_code/custom_lib/features/videocalls/src/widgets/videocall_lobby/videocall_lobby_widget.dart'; import 'package:flutter/material.dart'; import 'package:flutter/widgets.dart'; import 'package:zego_uikit_prebuilt_call/zego_uikit_prebuilt_call.dart'; import 'package:zego_uikit_signaling_plugin/zego_uikit_signaling_plugin.dart'; import '../actions/on_error_action.dart'; import '../actions/on_outgoing_call_accepted_action.dart'; import '../actions/on_outgoing_call_rejected_cause_busy_action.dart'; import '../actions/on_outgoing_call_timeout_action.dart'; import '../constants/videocalls_constants.dart'; import '../models/video_call_duration_model.dart'; import '../utils/get_doc_ref_by_doc_id.dart'; import '../actions/on_hang_up_confirmation_action.dart'; import '../widgets/CustomZegoCallBottomBar/custom_zego_call_bottom_bar_widget.dart'; class VideocallsService { late final GlobalKey globalCallNavigatorKey; String? _userID; late final VideoCallDurationModel _videoCallDurationModel; VideoCallDurationModel get videoCallDurationModel => _videoCallDurationModel; VideocallsService({ required GlobalKey navigatorKey, }) { globalCallNavigatorKey = navigatorKey; debugPrint( "-- VideocallsService -- init", ); _videoCallDurationModel = VideoCallDurationModel(const Duration(seconds: 0)); /// initialized ZegoUIKitPrebuiltCallInvitationService } Future onSetup() async { try { debugPrint("-- VideocallsService -- onSetup"); ZegoUIKitPrebuiltCallInvitationService() .setNavigatorKey(globalCallNavigatorKey); await ZegoUIKit().initLog(); ZegoUIKitPrebuiltCallInvitationService().useSystemCallingUI( [ZegoUIKitSignalingPlugin()], ); } catch (e) { debugPrint("-- VideocallsService -- onSetup - error: $e"); } } void onUserLogin({ required String userID, required String userName, }) { debugPrint("-- VideocallsService -- init"); if (ZegoUIKitPrebuiltCallInvitationService().isInit) { return; } _userID = userID; _videoCallDurationModel = VideoCallDurationModel(const Duration(seconds: 0)); /// initialized ZegoUIKitPrebuiltCallInvitationService /// when app's user is logged in or re-logged in /// We recommend calling this method as soon as the user logs in to your app. ZegoUIKitPrebuiltCallInvitationService().init( appID: VideocallsConstants.kAppID /*input your AppID*/, appSign: VideocallsConstants.kAppSign /*input your AppSign*/, userID: _userID!, userName: userName, plugins: [ ZegoUIKitSignalingPlugin(), ], notificationConfig: ZegoCallInvitationNotificationConfig( androidNotificationConfig: ZegoCallAndroidNotificationConfig( showFullScreen: true, ), ), requireConfig: (ZegoCallInvitationData data) { final config = ZegoUIKitPrebuiltCallConfig.oneOnOneVideoCall(); config.video = ZegoUIKitVideoConfig.preset540P(); // Modify your custom configurations here. config.duration = ZegoCallDurationConfig( // isVisible: true, isVisible: false, onDurationUpdate: (Duration duration) { _videoCallDurationModel.update(duration); if (duration.inSeconds >= VideocallsConstants.kHangUpCallAfterInSeconds) { ZegoUIKitPrebuiltCallController() .hangUp(globalCallNavigatorKey.currentState!.context); } }, ); config.layout = ZegoLayout.pictureInPicture( smallViewSize: const Size(120, 90), ); // Custom handlers config.layout = ZegoLayout.pictureInPicture( showNewScreenSharingViewInFullscreenMode: false, ); config.topMenuBar = ZegoCallTopMenuBarConfig( isVisible: false, ); // todo: maybe use standard realization config.bottomMenuBar = ZegoCallBottomMenuBarConfig( backgroundColor: Colors.white, hideAutomatically: false, hideByClick: false, buttons: List.empty(), ); config.foreground = CustomZegoCallBottomBar( userID: _userID!, globalCallNavigatorKey: globalCallNavigatorKey, ); return config; }, uiConfig: ZegoCallInvitationUIConfig( prebuiltWithSafeArea: false, declineButton: ZegoCallButtonUIConfig( visible: false, ), acceptButton: ZegoCallButtonUIConfig( visible: false, ), cancelButton: ZegoCallButtonUIConfig( visible: false, ), callingBackgroundBuilder: (context, size, info) { final callerRef = getDocRefByDocId(info.inviter.id, 'users'); debugPrint( '-- ZegoUIKitPrebuiltCallInvitationService -- callingBackgroundBuilder: ${callerRef.id}'); return VideocallLobbyWidget( userRef: callerRef, acceptButtonCallback: () => ZegoUIKitPrebuiltCallInvitationService().accept(), declineButtonCallback: () => ZegoUIKitPrebuiltCallInvitationService().reject(), isIncomingCall: callerRef != getDocRefByDocId(_userID!, 'users'), ); }, ), events: ZegoUIKitPrebuiltCallEvents( onError: (ZegoUIKitError error) { debugPrint( '-- ZegoUIKitPrebuiltCallEvents -- onError: ${error.toString()}'); }, onHangUpConfirmation: (event, onHangUpConfirmation) async { final result = await onHangUpConfirmationAction( event.context, ); return result; }, onCallEnd: (event, onCallEnd) async { await onCallEndAction( getDocRefByDocId(_userID!, 'users'), ); // todo: maybe navigate to another screen }, ), invitationEvents: ZegoUIKitPrebuiltCallInvitationEvents( onOutgoingCallTimeout: (callID, callees, isVideoCall) async { await onOutgoingCallTimeoutAction( context: globalCallNavigatorKey.currentState!.context, callID: callID, calleeUser: callees.first, customData: isVideoCall ? 'true' : 'false', ); }, onOutgoingCallRejectedCauseBusy: (callID, callee, customData) async { await onOutgoingCallRejectedCauseBusyAction( context: globalCallNavigatorKey.currentState!.context, callID: callID, calleeUser: callee, customData: customData, ); }, onOutgoingCallDeclined: (callID, callee, customData) async { await onOutgoingCallDeclinedAction( context: globalCallNavigatorKey.currentState!.context, callID: callID, calleeUser: callee, customData: customData, ); }, onError: (error) async { debugPrint( '-- ZegoUIKitPrebuiltCallInvitationEvents -- onError: ${error.toString()}', ); await onErrorAction( context: globalCallNavigatorKey.currentState!.context, error: error, ); }, onOutgoingCallAccepted: (callID, callee) async { await onOutgoingCallAcceptedAction( getDocRefByDocId(_userID!, 'users'), ); }, ), ); } /// on App's user logout void onUserLogout() { debugPrint("-- VideocallsService -- onUserLogout"); ZegoUIKitPrebuiltCallInvitationService().uninit(); } /// call user /// show loader in UI Future sendCallInvite({ required String calleeId, String? caleeName, }) async { final invitees = [ ZegoCallUser( calleeId, caleeName ?? 'User', ), ]; await ZegoUIKitPrebuiltCallInvitationService().send( invitees: invitees, isVideoCall: true, resourceID: 'zego_call', ); } } ```

  1. Connected the service with libraries
main.dart

```dart void main() async { WidgetsFlutterBinding.ensureInitialized(); GoRouter.optionURLReflectsImperativeAPIs = true; usePathUrlStrategy(); await initFirebase(); // Start initial custom actions code await actions.setOnlyPortraitOrientations(); final globalCallNavigatorKey = GlobalKey(); await dependenciesManager( globalCallNavigatorKey, ); await actions.extraLoginHandler(); /// other code final videocallsService = GetIt.I.get(); await videocallsService.onSetup(); /// other code runApp(ChangeNotifierProvider( create: (context) => appState, child: const MyApp(), )); } /// other code class _MyAppState extends State { @override void initState() { final videocallsService = GetIt.I.get(); /// other code // add in navigatorKey in GoRouter _router = createRouter( _appStateNotifier, videocallsService.globalCallNavigatorKey, ); /// other code } @override Widget build(BuildContext context) { return MaterialApp.router( title: 'MazeVideoTinder', localizationsDelegates: const [ FFLocalizationsDelegate(), GlobalMaterialLocalizations.delegate, GlobalWidgetsLocalizations.delegate, GlobalCupertinoLocalizations.delegate, ], locale: _locale, supportedLocales: const [ Locale('en'), Locale('ru'), ], theme: ThemeData( brightness: Brightness.light, ), themeMode: _themeMode, routerConfig: _router, ); } } ```

  1. When an autologin or login is made into the application, the method is called
extra_login_handler.dart

```dart Future extraLoginHandler() async { try { final currentUser = await firebase_auth.FirebaseAuth.instance.currentUser; if (currentUser == null) { return; } debugPrint('-- extraLoginHandler - currentUser?.uid: ${currentUser?.uid}'); /// other code final videocallsService = GetIt.I.get(); videocallsService.onUserLogin( userID: currentUser.uid, userName: currentUser.displayName ?? 'Unnamed user', ); } catch (e) { debugPrint('-- extraLoginHandler'); } } ```

  1. When i need to call to another user i call the following method:
start_call.dart

```dart import 'package:app_name/custom_code/custom_lib/features/videocalls/src/services/videocalls_service.dart'; import 'package:get_it/get_it.dart'; Future startCall( DocumentReference calleeRef, String calleeName, ) async { try { debugPrint('-- startCall - calleeRef: $calleeRef'); final videocallsService = GetIt.I.get(); await videocallsService.sendCallInvite( calleeId: calleeRef.id, caleeName: calleeName, ); } catch (e) { debugPrint('-- startCall: $e'); } } ```

yoer commented 4 months ago

This is because you haven't executed ZegoUIKitPrebuiltCallInvitationService.init before call, or you executed ZegoUIKitPrebuiltCallInvitationService.uninit it after calling init.

  1. You can try to debug by yourself to see if the assignment is normal (whether the ZegoCallInvitationInternalInstance.registe function is executed and the ZegoCallInvitationInternalInstance.unregiste function is not executed, ZegoCallInvitationInternalInstance is in _zego_uikit_prebuilt_call/lib/src/invitation/internal/internalinstance.dart)

  2. You can send the log over to have a look. The log directory is at _/sdcard/Android/data/${your_bundle_id}/files/zego_prebuilt/uikit/Logs_

yokawaiik commented 4 months ago

I found out the following in the logs directory:

06052024.log

``` {call} {call invitation service(245149572)} {using system calling ui, plugins size: 1} {06/05/2024 07:25:28} {INFO} {call} {call invitation service(245149572)} {register background message handler} {06/05/2024 07:25:28} {INFO} {uikit} {signaling core data} {init data.} {06/05/2024 07:25:28} {INFO} {uikit} {signaling invitation data} {init} {06/05/2024 07:25:28} {INFO} {uikit} {signaling advance invitation data} {init} {06/05/2024 07:25:28} {INFO} {log} {init} {==========================================Logs Configuration added.} {06/05/2024 07:25:29} {INFO} {log} {init} {==========================================Logs Configuration added.} {06/05/2024 07:25:29} {INFO} {adapter} {system service} {init system service} {06/05/2024 07:25:29} {INFO} {call} {call invitation service(664652913)} {using system calling ui, plugins size: 1} {06/05/2024 07:33:36} {INFO} {call} {call invitation service(664652913)} {register background message handler} {06/05/2024 07:33:36} {INFO} {uikit} {signaling core data} {init data.} {06/05/2024 07:33:36} {INFO} {uikit} {signaling invitation data} {init} {06/05/2024 07:33:36} {INFO} {uikit} {signaling advance invitation data} {init} {06/05/2024 07:33:36} {INFO} {log} {init} {==========================================Logs Configuration added.} {06/05/2024 07:33:36} {INFO} {log} {init} {==========================================Logs Configuration added.} {06/05/2024 07:33:36} {INFO} {adapter} {system service} {init system service} {06/05/2024 07:33:36} {INFO} {call} {call invitation service(373218972)} {using system calling ui, plugins size: 1} {06/05/2024 07:39:31} {INFO} {call} {call invitation service(373218972)} {register background message handler} {06/05/2024 07:39:31} {INFO} {uikit} {signaling core data} {init data.} {06/05/2024 07:39:31} {INFO} {uikit} {signaling invitation data} {init} {06/05/2024 07:39:31} {INFO} {uikit} {signaling advance invitation data} {init} {06/05/2024 07:39:31} {INFO} {log} {init} {==========================================Logs Configuration added.} {06/05/2024 07:39:31} {INFO} {log} {init} {==========================================Logs Configuration added.} {06/05/2024 07:39:31} {INFO} {adapter} {system service} {init system service} {06/05/2024 07:39:31} {INFO} {call} {call invitation service(337690626)} {using system calling ui, plugins size: 1} {06/05/2024 07:42:00} {INFO} {call} {call invitation service(337690626)} {register background message handler} {06/05/2024 07:42:00} {INFO} {uikit} {signaling core data} {init data.} {06/05/2024 07:42:00} {INFO} {uikit} {signaling invitation data} {init} {06/05/2024 07:42:00} {INFO} {uikit} {signaling advance invitation data} {init} {06/05/2024 07:42:00} {INFO} {log} {init} {==========================================Logs Configuration added.} {06/05/2024 07:42:00} {INFO} {log} {init} {==========================================Logs Configuration added.} {06/05/2024 07:42:00} {INFO} {adapter} {system service} {init system service} {06/05/2024 07:42:00} {INFO} {call} {controller.invitation} {send call invitation} {06/05/2024 07:53:35} {INFO} {call} {controller.invitation} {send call invitation} {06/05/2024 07:53:36} {INFO} {call} {call invitation service(784450052)} {using system calling ui, plugins size: 1} {06/05/2024 07:55:58} {INFO} {call} {call invitation service(784450052)} {register background message handler} {06/05/2024 07:55:58} {INFO} {uikit} {signaling core data} {init data.} {06/05/2024 07:55:58} {INFO} {uikit} {signaling invitation data} {init} {06/05/2024 07:55:58} {INFO} {uikit} {signaling advance invitation data} {init} {06/05/2024 07:55:58} {INFO} {log} {init} {==========================================Logs Configuration added.} {06/05/2024 07:55:58} {INFO} {log} {init} {==========================================Logs Configuration added.} {06/05/2024 07:55:58} {INFO} {adapter} {system service} {init system service} {06/05/2024 07:55:58} {INFO} {call} {call invitation service(344440911)} {using system calling ui, plugins size: 1} {06/05/2024 07:58:45} {INFO} {call} {call invitation service(344440911)} {register background message handler} {06/05/2024 07:58:45} {INFO} {uikit} {signaling core data} {init data.} {06/05/2024 07:58:45} {INFO} {uikit} {signaling invitation data} {init} {06/05/2024 07:58:45} {INFO} {uikit} {signaling advance invitation data} {init} {06/05/2024 07:58:45} {INFO} {log} {init} {==========================================Logs Configuration added.} {06/05/2024 07:58:45} {INFO} {log} {init} {==========================================Logs Configuration added.} {06/05/2024 07:58:45} {INFO} {adapter} {system service} {init system service} {06/05/2024 07:58:45} {INFO} {call} {call invitation service(44248487)} {using system calling ui, plugins size: 1} {06/05/2024 08:02:10} {INFO} {call} {call invitation service(44248487)} {register background message handler} {06/05/2024 08:02:10} {INFO} {uikit} {signaling core data} {init data.} {06/05/2024 08:02:10} {INFO} {uikit} {signaling invitation data} {init} {06/05/2024 08:02:10} {INFO} {uikit} {signaling advance invitation data} {init} {06/05/2024 08:02:10} {INFO} {log} {init} {==========================================Logs Configuration added.} {06/05/2024 08:02:10} {INFO} {log} {init} {==========================================Logs Configuration added.} {06/05/2024 08:02:10} {INFO} {adapter} {system service} {init system service} {06/05/2024 08:02:10} {INFO} {call} {call invitation service(407709620)} {using system calling ui, plugins size: 1} {06/05/2024 08:03:07} {INFO} {call} {call invitation service(407709620)} {register background message handler} {06/05/2024 08:03:07} {INFO} {uikit} {signaling core data} {init data.} {06/05/2024 08:03:07} {INFO} {uikit} {signaling invitation data} {init} {06/05/2024 08:03:07} {INFO} {uikit} {signaling advance invitation data} {init} {06/05/2024 08:03:07} {INFO} {log} {init} {==========================================Logs Configuration added.} {06/05/2024 08:03:07} {INFO} {log} {init} {==========================================Logs Configuration added.} {06/05/2024 08:03:07} {INFO} {adapter} {system service} {init system service} {06/05/2024 08:03:07} {INFO} {call} {call invitation service(1026281182)} {using system calling ui, plugins size: 1} {06/05/2024 08:03:57} {INFO} {call} {call invitation service(1026281182)} {register background message handler} {06/05/2024 08:03:57} {INFO} {uikit} {signaling core data} {init data.} {06/05/2024 08:03:57} {INFO} {uikit} {signaling invitation data} {init} {06/05/2024 08:03:57} {INFO} {uikit} {signaling advance invitation data} {init} {06/05/2024 08:03:57} {INFO} {log} {init} {==========================================Logs Configuration added.} {06/05/2024 08:03:57} {INFO} {log} {init} {==========================================Logs Configuration added.} {06/05/2024 08:03:57} {INFO} {adapter} {system service} {init system service} {06/05/2024 08:03:57} {INFO} ```

yokawaiik commented 4 months ago

It seems I found what the problem is. Indeed, in my service ZegoUIKitPrebuiltCallInvitationService().init simply did not execute because there was an error overriding the final field.

_videoCallDurationModel = VideoCallDurationModel(const Duration(seconds: 0));

Therefore, the error does not actually affect the package.

After I corrected it to

 _videoCallDurationModel.update(const Duration(seconds: 0));

The user's call began to be displayed.

Thank you for your help!

Have a nice day!