ConnectyCube / connectycube-reactnative-samples

Chat and Video Chat code samples for React Native, ConnectyCube
https://connectycube.com
Apache License 2.0
124 stars 111 forks source link

Background call notifications and CallKeep is not working when app is in foreground and background or (killed) state #307

Open muneeb-mt opened 1 year ago

muneeb-mt commented 1 year ago

Please help us in the complete integration of CallKeep in our react-native application. We have already integrated the files and setup everything according to the documentation and !!RNVideoCHAT!! project. Please arrange one of your engineer to engage with us on this matter and help us to resolve all issues. Thank you. Looking forward to you.

ccvlad commented 1 year ago

What platform do you use? Android, iOS or both? Please share your package.json or snippet from it with libraries and they versions. Would be helpful if you have some logs or you are able to describe what actually doesn't work as expected. Please provide more info.

muneeb-mt commented 1 year ago

{ "name": "sensights", "version": "0.0.1", "private": true, "scripts": { "android": "react-native run-android", "cc": "rimraf node_modules/.cache/babel-loader/*,", "ios": "npm run cc && react-native run-ios", "start": "react-native start", "test": "jest", "lint": "eslint . --ext .js,.jsx,.ts,.tsx", "postinstall": "npx patch-package", "release-development": "ENVFILE=.env.development react-native run-android --variant=release" }, "dependencies": { "@react-native-community/async-storage": "^1.12.1", "@react-native-community/datetimepicker": "^6.7.0", "@react-native-community/masked-view": "^0.1.11", "@react-native-community/netinfo": "^9.3.6", "@react-native-community/push-notification-ios": "^1.10.1", "@react-native-firebase/analytics": "^16.5.0", "@react-native-firebase/app": "^16.4.4", "@react-native-firebase/crashlytics": "^16.4.4", "@react-native-firebase/messaging": "^16.4.6", "@react-native-google-signin/google-signin": "^9.0.0", "@react-native-picker/picker": "^2.4.8", "@react-navigation/bottom-tabs": "^6.4.0", "@react-navigation/native": "^6.0.13", "@react-navigation/native-stack": "^6.9.1", "@reduxjs/toolkit": "^1.9.0", "@taoqf/react-native-mqtt": "^3.0.4", "@tranzerdev/react-native-user-defaults": "github:ConnectyCube/react-native-userdefaults#main", "axios": "^0.24.0", "buffer": "^6.0.3", "hex2dec": "^1.1.2", "jetifier": "^2.0.0", "lodash": "^4.17.21", "moment": "^2.29.4", "moment-timezone": "^0.5.40", "patch-package": "^6.5.0", "postinstall-postinstall": "^2.1.0", "@taoqf/react-native-mqtt": "^3.0.4", "pushy-react-native": "^1.0.29", "react": "18.1.0", "react-native": "0.70.5", "react-native-actionsheet": "^2.4.2", "react-native-awesome-alerts": "^2.0.0", "react-native-background-fetch": "^4.1.0", "react-native-background-geolocation": "^4.0.1", "react-native-background-timer": "^2.4.1", "react-native-ble-plx": "^2.0.3", "react-native-callkeep": "github:react-native-webrtc/react-native-callkeep#master", "react-native-can-draw-overlays": "^1.0.0", "react-native-code-push": "^7.0.5", "react-native-collapsible": "^1.6.0", "react-native-config": "^1.4.11", "react-native-confirmation-code-field": "^7.3.1", "react-native-connectycube": "^3.21.0", "react-native-contacts": "^7.0.5", "react-native-device-info": "^10.3.0", "react-native-dialog": "^9.3.0", "react-native-document-picker": "^8.1.2", "react-native-dropdown-picker": "^5.4.3", "react-native-elements": "^3.4.2", "react-native-error-boundary": "^1.1.16", "react-native-event-listeners": "^1.0.7", "react-native-fast-image": "^8.6.3", "react-native-fbsdk-next": "^11.1.0", "react-native-file-viewer": "^2.1.5", "react-native-fs": "^2.20.0", "react-native-gesture-handler": "^2.8.0", "react-native-google-fit": "^0.19.1", "react-native-health": "^1.13.0", "react-native-icon-badge": "^1.1.3", "react-native-image-picker": "^4.10.1", "react-native-immediate-phone-call": "^2.0.0", "react-native-incall-manager": "^4.0.0", "react-native-invoke-app": "github:ConnectyCube/react-native-invoke-app#master", "react-native-keep-awake": "^4.0.0", "react-native-keyboard-aware-scroll-view": "^0.9.5", "react-native-linear-gradient": "^2.6.2", "react-native-loading-spinner-overlay": "^3.0.1", "react-native-maps": "^1.3.2", "react-native-material-dropdown": "^0.11.1", "react-native-modal": "^13.0.1", "react-native-modal-datetime-picker": "^14.0.0", "react-native-nodemediaclient": "^0.2.18", "react-native-notifications": "^4.3.3", "react-native-permissions": "^3.6.1", "react-native-picker-select": "^8.0.4", "react-native-push-notification": "^8.1.1", "react-native-reanimated": "^2.12.0", "react-native-restart": "^0.0.24", "react-native-safe-area-context": "^4.4.1", "react-native-safe-area-view": "^1.1.1", "react-native-screens": "^3.18.2", "react-native-share": "^8.0.0", "react-native-simple-toast": "^1.1.4", "react-native-slider": "^0.11.0", "react-native-snackbar": "^2.4.0", "react-native-sound": "^0.11.2", "react-native-splash-screen": "^3.3.0", "react-native-svg": "^13.6.0", "react-native-svg-transformer": "^1.0.0", "react-native-swiper": "^1.6.0", "react-native-vector-icons": "^9.2.0", "react-native-version-check": "^3.4.3", "react-native-veyetals-native": "^1.5.5", "react-native-webrtc": "^1.92.0", "react-native-webview": "^11.23.1", "react-native-youtube-iframe": "^2.2.2", "react-native-zendesk-chat": "^0.4.1", "react-navigation": "^4.4.4", "react-navigation-stack": "^2.10.4", "react-navigation-transitions": "^1.0.12", "react-redux": "^8.0.5", "redux-persist": "^6.0.0", "redux-saga": "^1.2.1", "rn-fetch-blob": "^0.12.0", "rn-secure-storage": "^2.0.7", "socket.io-client": "^4.5.3", "styled-content-loader": "^1.2.2", "victory-native": "^36.6.8" }, "resolutions": { "react-native-reanimated": "^2.9.1" }, "devDependencies": { "@babel/core": "^7.12.9", "@babel/runtime": "^7.12.5", "@react-native-community/eslint-config": "^2.0.0", "@tsconfig/react-native": "^2.0.2", "@types/jest": "^26.0.23", "@types/react": "^18.0.21", "@types/react-native": "^0.70.6", "@types/react-test-renderer": "^18.0.0", "@typescript-eslint/eslint-plugin": "^5.37.0", "@typescript-eslint/parser": "^5.37.0", "babel-jest": "^26.6.3", "babel-plugin-module-resolver": "^4.1.0", "eslint": "^7.32.0", "jest": "^26.6.3", "metro-react-native-babel-preset": "0.72.3", "react-test-renderer": "18.1.0", "typescript": "^4.8.3" }, "jest": { "preset": "react-native", "moduleFileExtensions": [ "ts", "tsx", "js", "jsx", "json", "node" ] } }

muneeb-mt commented 1 year ago

This is the package.json file. The point is the background call feature implementation using KeepCall is not working

ccvlad commented 1 year ago

Is it possible to capture logs from caller and callee sides when incoming call should present? Use real devices - Android/iOS to make a call and Android to receive the call. It will helpful to find your issues. Otherwise I will build a project by the guide (video calling sample + notifications + callkeep) with versions of libs from your package.json to check how it works. It will take some time. Then we look for problems on your side

muneeb-mt commented 1 year ago

IMG-20230206-WA0005 Here are some logs

muneeb-mt commented 1 year ago

@ccvlad How much time you will required to create a project and verify all? And we can send call these required screenshots by tomorrow morning. I will request you to create a project using package.json to check and verify all the functionality. I can provide you the screenshots callee and caller side by tomorrow @ccvlad

ccvlad commented 1 year ago

I will try to check it today but I not sure that it will be tested before tomorrow.

Initially, I thought that you didn't fully configure the push-notification /VOIP. But I can't write my guesses as I need more details from you.

I need to build a project locally to make sure everything works well on our side.

muneeb-mt commented 1 year ago

Please check it at your side if it is working fine for you. In the meantime, I will double check if I have configured push notifications and VOIP properly.

muneeb-mt commented 1 year ago

@ccvlad is there any response?

ccvlad commented 1 year ago

I will update you today

muneeb-mt commented 1 year ago

sure - i will wait @ccvlad

ccvlad commented 1 year ago

Hi @muneeb-mt

I have upgraded RNVideoChat sample to React Native 0.70.5 and configured notifications with the callkeep from scratch.

The callkeep works on iOS. On Android the callkeep plays ringtone but doesn't show incoming call. I will resolve it and let you know.

What behavior did you see on your side?

ccvlad commented 1 year ago

@muneeb-mt

You can check pull request's diffs if it is helpful. I have upgraded the RNVideoChat the sample to React Native 0.70.5 and reviewed the CallKeep setup by our guide. CallKeep works for iOS and Android platforms.

Lets consider what can we do to setup CallKeep for you. Please check one more time the Push Notifications guide. Then describe your app's behavior for Android and iOS. I would ask you questions related to code/configs or will answer to your answers.

faisalur-rehman commented 1 year ago

@ccvlad Push notification guide link is broken. It says 404: Not Found

DaveLomber commented 1 year ago

@faisalur-rehman which one is broken?

faisalur-rehman commented 1 year ago

@faisalur-rehman which one is broken?

This link is broken which @ccvlad mentioned in his above comment Push Notifications guide

ccvlad commented 1 year ago

hm, I can open it - https://developers.connectycube.com/reactnative/push-notifications?id=push-notifications

faisalur-rehman commented 1 year ago

I was able to open the link in incognito but it does not open in normal window for me.

image
faisalur-rehman commented 1 year ago

I think it is an issue with my browser. I will follow the guide and will get back to you on this

faisalur-rehman commented 1 year ago

@ccvlad I was going through the connectycube code for background call implementation and saw this code in AppDelegate.mm here

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handlePushKitNotificationReceived:) name:RNPushKitNotificationReceived object:nil]; [[NSUserDefaults standardUserDefaults] removeObjectForKey:@"voipIncomingCallSessions"];

But when I added this code into my code, it threw this error when building the project: Use of undefined identifier RNPushKitNotificationReceived I tried finding the identifier in connectycube RNVideoChat project but couldn't find one. Do I need to declare it somewhere or am I doing something wrong?

DaveLomber commented 1 year ago

@faisalur-rehman make sure you also have

#import "RNNotifications.h"
#import "RNEventEmitter.h"

RNPushKitNotificationReceived is a part of https://github.com/wix/react-native-notifications lib, which is defined in RNEventEmitter.h file

faisalur-rehman commented 1 year ago

@DaveLomber @ccvlad I completed push notification guide setup and added APNs certificate on connnectycube admin console. Made few changes in AppDelegate.mm file. After these changes, I am able to receive the call in background state for IOS but there are few issues.

  1. When in background, the pop up to pick or reject the call has name Unknown rather than the caller name. I am attaching Screenshot for you to see. 2- Sometimes, when the call is accepted by the recipient, it is not reflected on the caller side. 3- It is not working in release mode for other users. Works on my phone only(the one that I connected in debug mode) 4- Does not work when the app is in killed state. 5- It keeps calling on the caller side after picking up a call when the phone was locked Here is my AppDelegate.mm code
#import "AppDelegate.h"
#import "RCTAppleHealthKit.h"

#import <React/RCTBridge.h>
#import <React/RCTBundleURLProvider.h>
#import <React/RCTRootView.h>
#import <GoogleMaps/GoogleMaps.h>
#import <React/RCTAppSetupUtils.h>
#import <Firebase.h>
#import <UserNotifications/UserNotifications.h>
#import <RNCPushNotificationIOS.h>
#import <PushyModule.h>
#import <CodePush/CodePush.h>
#import "RNCallKeep.h"
#import "RNNotifications.h"
#import "RNEventEmitter.h"

#import "RNSplashScreen.h"  // here
#import <FBSDKCoreKit/FBSDKCoreKit-swift.h>
#import <RNGoogleSignin/RNGoogleSignin.h>
#import <React/RCTLinkingManager.h>
#if RCT_NEW_ARCH_ENABLED
#import <React/CoreModulesPlugins.h>
#import <React/RCTCxxBridgeDelegate.h>
#import <React/RCTFabricSurfaceHostingProxyRootView.h>
#import <React/RCTSurfacePresenter.h>
#import <React/RCTSurfacePresenterBridgeAdapter.h>
#import <ReactCommon/RCTTurboModuleManager.h>

#import <react/config/ReactNativeConfig.h>

static NSString *const kRNConcurrentRoot = @"concurrentRoot";

@interface AppDelegate () <RCTCxxBridgeDelegate, RCTTurboModuleManagerDelegate> {
  RCTTurboModuleManager *_turboModuleManager;
  RCTSurfacePresenterBridgeAdapter *_bridgeAdapter;
  std::shared_ptr<const facebook::react::ReactNativeConfig> _reactNativeConfig;
  facebook::react::ContextContainer::Shared _contextContainer;
}
@end
#endif

@implementation AppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
  RCTAppSetupPrepareApp(application);

  RCTBridge *bridge = [[RCTBridge alloc] initWithDelegate:self launchOptions:launchOptions];

#if RCT_NEW_ARCH_ENABLED
  _contextContainer = std::make_shared<facebook::react::ContextContainer const>();
  _reactNativeConfig = std::make_shared<facebook::react::EmptyReactNativeConfig const>();
  _contextContainer->insert("ReactNativeConfig", _reactNativeConfig);
  _bridgeAdapter = [[RCTSurfacePresenterBridgeAdapter alloc] initWithBridge:bridge contextContainer:_contextContainer];
  bridge.surfacePresenter = _bridgeAdapter.surfacePresenter;
#endif

  NSDictionary *initProps = [self prepareInitialProps];
  UIView *rootView = RCTAppSetupDefaultRootView(bridge, @"sensights", initProps);

  if (@available(iOS 13.0, *)) {
    rootView.backgroundColor = [UIColor systemBackgroundColor];
  } else {
    rootView.backgroundColor = [UIColor whiteColor];
  }

  self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
  UIViewController *rootViewController = [UIViewController new];
  rootViewController.view = rootView;
  self.window.rootViewController = rootViewController;
  [self.window makeKeyAndVisible];
  [FIRApp configure];
  [GMSServices provideAPIKey:@"AIzaSyCM3R8cZQht5FIFqWEoEGiJNiquht_CVUU"];
  [PushyModule didFinishLaunchingWithOptions:launchOptions];

  UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
  center.delegate = self;

  [RNSplashScreen show];  // here
  [RNNotifications startMonitorNotifications];
  [RNNotifications startMonitorPushKitNotifications];
  [[FBSDKApplicationDelegate sharedInstance] application:application
                           didFinishLaunchingWithOptions:launchOptions];
   [[NSNotificationCenter defaultCenter] addObserver:self
                                            selector:@selector(handlePushKitNotificationReceived:)
                                                name:RNPushKitNotificationReceived
                                              object:nil];
   // cleanup
   [[NSUserDefaults standardUserDefaults] removeObjectForKey:@"voipIncomingCallSessions"];

  return YES;
}
-(void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions options))completionHandler
{
  completionHandler(UNNotificationPresentationOptionSound | UNNotificationPresentationOptionAlert | UNNotificationPresentationOptionBadge);
}

- (void)handlePushKitNotificationReceived:(NSNotification *)notification {
  UIApplicationState state = [[UIApplication sharedApplication] applicationState];

  if (state == UIApplicationStateBackground || state == UIApplicationStateInactive) {

    // save call info to user defaults
    NSMutableDictionary *callsInfo = [[[NSUserDefaults standardUserDefaults] objectForKey:@"voipIncomingCallSessions"] mutableCopy];
    if (callsInfo == nil) {
      callsInfo = [NSMutableDictionary dictionary];
    }
    [callsInfo setObject:@{
      @"initiatorId": notification.userInfo[@"initiatorId"],
      @"opponentsIds": notification.userInfo[@"opponentsIds"],
      @"handle": notification.userInfo[@"handle"],
      @"callType": notification.userInfo[@"callType"]
    } forKey:notification.userInfo[@"uuid"]];
    [[NSUserDefaults standardUserDefaults] setObject:callsInfo forKey:@"voipIncomingCallSessions"];

    // show CallKit incoming call screen
    [RNCallKeep reportNewIncomingCall: notification.userInfo[@"uuid"]
                               handle: notification.userInfo[@"handle"]
                           handleType: @"generic"
                             hasVideo: [notification.userInfo[@"callType"] isEqual: @"video"]
                  localizedCallerName: notification.userInfo[@"handle"]
                      supportsHolding: YES
                         supportsDTMF: YES
                     supportsGrouping: YES
                   supportsUngrouping: YES
                          fromPushKit: YES
                              payload: notification.userInfo
                withCompletionHandler: nil];
  } else {
    // when an app is in foreground -> will show the in-app UI for incoming call
  }
}

/// This method controls whether the `concurrentRoot`feature of React18 is turned on or off.
///
/// @see: https://reactjs.org/blog/2022/03/29/react-v18.html
/// @note: This requires to be rendering on Fabric (i.e. on the New Architecture).
/// @return: `true` if the `concurrentRoot` feture is enabled. Otherwise, it returns `false`.
- (BOOL)concurrentRootEnabled
{
  // Switch this bool to turn on and off the concurrent root
  return true;
}

- (NSDictionary *)prepareInitialProps
{
  NSMutableDictionary *initProps = [NSMutableDictionary new];

#ifdef RCT_NEW_ARCH_ENABLED
  initProps[kRNConcurrentRoot] = @([self concurrentRootEnabled]);
#endif

  return initProps;
}

- (NSURL *)sourceURLForBridge:(RCTBridge *)bridge
{
#if DEBUG
  return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index"];
#else
  return [CodePush bundleURL];

#endif
}

#if RCT_NEW_ARCH_ENABLED

#pragma mark - RCTCxxBridgeDelegate

- (std::unique_ptr<facebook::react::JSExecutorFactory>)jsExecutorFactoryForBridge:(RCTBridge *)bridge
{
  _turboModuleManager = [[RCTTurboModuleManager alloc] initWithBridge:bridge
                                                             delegate:self
                                                            jsInvoker:bridge.jsCallInvoker];
  return RCTAppSetupDefaultJsExecutorFactory(bridge, _turboModuleManager);
}

#pragma mark RCTTurboModuleManagerDelegate

- (Class)getModuleClassFromName:(const char *)name
{
  return RCTCoreModulesClassProvider(name);
}

- (std::shared_ptr<facebook::react::TurboModule>)getTurboModule:(const std::string &)name
                                                      jsInvoker:(std::shared_ptr<facebook::react::CallInvoker>)jsInvoker
{
  return nullptr;
}

- (std::shared_ptr<facebook::react::TurboModule>)getTurboModule:(const std::string &)name
                                                     initParams:
                                                         (const facebook::react::ObjCTurboModule::InitParams &)params
{
  return nullptr;
}

- (id<RCTTurboModule>)getModuleInstanceFromClass:(Class)moduleClass
{
  return RCTAppSetupDefaultModuleFromClass(moduleClass);
}

// - (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
// {
//  [RNCPushNotificationIOS didRegisterForRemoteNotificationsWithDeviceToken:deviceToken];
// }
// // Required for the notification event. You must call the completion handler after handling the remote notification.
// - (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
// fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler
// {
//   [RNCPushNotificationIOS didReceiveRemoteNotification:userInfo fetchCompletionHandler:completionHandler];
// }
// // Required for the registrationError event.
// - (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error
// {
//  [RNCPushNotificationIOS didFailToRegisterForRemoteNotificationsWithError:error];
// }

- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
  [RNNotifications didRegisterForRemoteNotificationsWithDeviceToken:deviceToken];
}
- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error {
  [RNNotifications didFailToRegisterForRemoteNotificationsWithError:error];
}
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult result))completionHandler {
  [RNNotifications didReceiveBackgroundNotification:userInfo withCompletionHandler:completionHandler];
}

// Required for localNotification event
- (void)userNotificationCenter:(UNUserNotificationCenter *)center
didReceiveNotificationResponse:(UNNotificationResponse *)response
         withCompletionHandler:(void (^)(void))completionHandler
{
  [RNCPushNotificationIOS didReceiveNotificationResponse:response];
}

- (BOOL)application:(UIApplication )application openURL:(nonnull NSURL )url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation options:(nonnull NSDictionary<NSString ,id> )options {
  return [[FBSDKApplicationDelegate sharedInstance] application:application openURL:url options:options] || [RNGoogleSignin application:application openURL:url options:options] || [RCTLinkingManager application:application openURL:url sourceApplication:sourceApplication annotation:annotation options:options];
}

- (BOOL)application:(UIApplication *)application continueUserActivity:(nonnull NSUserActivity *)userActivity
 restorationHandler:(nonnull void (^)(NSArray<id<UIUserActivityRestoring>> * _Nullable))restorationHandler
{
 return [RCTLinkingManager application:application
                  continueUserActivity:userActivity
                    restorationHandler:restorationHandler];
}
- (BOOL)application:(UIApplication *)application
continueUserActivity:(NSUserActivity *)userActivity
  restorationHandler:(void(^)(NSArray * __nullable restorableObjects))restorationHandler
{
  return [RNCallKeep application:application
           continueUserActivity:userActivity
             restorationHandler:restorationHandler];
}
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
 [RNNotifications didRegisterForRemoteNotificationsWithDeviceToken:deviceToken];
}
- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error {
 [RNNotifications didFailToRegisterForRemoteNotificationsWithError:error];
}
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult result))completionHandler {
 [RNNotifications didReceiveBackgroundNotification:userInfo withCompletionHandler:completionHandler];
}
#endif
@end

Here are some screehshots:

1 2 3

4

image

Thanks

ahmaddmuneeb commented 1 year ago

@DaveLomber @ccvlad Is there any update?

ccvlad commented 1 year ago

@ahmaddmuneeb

To solve "Unknown" you have to pass the right parameters to the push notification's payload in ConnectyCube.pushnotifications.events.create(..), try to modify title/body/message inside your params:

    const payload = JSON.stringify(params);
    const pushParameters = {
      notification_type: "push",
      user: { ids: recipientsUsersIds },
      environment: __DEV__ ? "development" : "production",
      message: ConnectyCube.pushnotifications.base64Encode(payload),
    };

    ConnectyCube.pushnotifications.events.create(pushParameters)

Pay attention to the guide to keep calling in background/locked mode - https://developers.connectycube.com/reactnative/videocalling?id=continue-call-in-background

To improve a chat connection (for calls signaling) you should manage it. The way is using ReactNative's AppState listener to define the background/foreground app's state. Check the chat connection (ConnectyCube.chat.isConnected) after the app is going to the foreground and do ConnectyCube.chat.connect(params) if it was disconnected. Also, a good way is to listen to the network state and do reconnect after your app goes from offline to online (check the lib @react-native-community/netinfo)

Unfortunately, I don't see any of your problems in the log above. Our RNVideoChat app is a demo app and it doesn't cover all cases, but you can find more information in our guide for React Native