Open w4ugit opened 6 months ago
The problem could be in your component re-render. Just track if it was re-rendered or it was fired twice. I bet it is re-render ) even without seeing other parts of your app.
To make sure it wasn't, I removed everything else and left only this code
import React, {useEffect} from 'react';
import i18n from 'i18next';
import {initReactI18next} from 'react-i18next';
import uk from './src/i18n/uk';
import en from './src/i18n/en';
import de from './src/i18n/de';
import es from './src/i18n/es';
import {Alert, NativeModules, Platform, Text} from 'react-native';
import VoipPushNotification from 'react-native-voip-push-notification';
const locale =
Platform.OS === 'ios'
? NativeModules.SettingsManager.settings.AppleLocale
: NativeModules.I18nManager.localeIdentifier;
i18n.use(initReactI18next).init({
compatibilityJSON: 'v3',
resources: {
en: en,
uk: uk,
de: de,
es: es,
},
lng: 'en',
interpolation: {
escapeValue: false,
},
});
const App = ({bgState}) => {
useEffect(() => {
if (Platform.OS === 'ios') {
VoipPushNotification.addEventListener('register', token => {});
VoipPushNotification.addEventListener('notification', notification => {
Alert.alert('Call answer');
VoipPushNotification.onVoipNotificationCompleted(notification.uuid);
});
VoipPushNotification.addEventListener('didLoadWithEvents', events => {
if (!events || !Array.isArray(events) || events.length < 1) {
return;
}
});
VoipPushNotification.registerVoipToken(); // --- register token
}
}, []);
return <Text>App</Text>;
};
export default App;
the problem has not gone away
Here is my AppDelegate.mm file
#import "AppDelegate.h"
#import <Firebase.h>
#import "RNBootSplash.h"
#import "RNCallKeep.h"
#import <React/RCTBundleURLProvider.h>
#import "Orientation.h"
#import <PushKit/PushKit.h>
#import "RNVoipPushNotificationManager.h"
#import "RNFBMessagingModule.h"
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.moduleName = @"Calls";
// You can add your custom initial props in the dictionary below.
// They will be passed down to the ViewController used by React Native.
self.initialProps = @{};
self.initialProps = [RNFBMessagingModule addCustomPropsToUserProps:nil withLaunchOptions:launchOptions];
[FIRApp configure];
[super application:application didFinishLaunchingWithOptions:launchOptions];
[RNBootSplash initWithStoryboard:@"BootSplash" rootView:self.window.rootViewController.view];
[RNVoipPushNotificationManager voipRegistration];
return YES;
}
- (NSURL *)sourceURLForBridge:(RCTBridge *)bridge
{
#if DEBUG
return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index"];
#else
return [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"];
#endif
}
/// 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` feature is enabled. Otherwise, it returns `false`.
- (BOOL)concurrentRootEnabled
{
return true;
}
- (BOOL)application:(UIApplication *)application
continueUserActivity:(NSUserActivity *)userActivity
restorationHandler:(void(^)(NSArray<id<UIUserActivityRestoring>> * __nullable restorableObjects))restorationHandler
{
return [RNCallKeep application:application
continueUserActivity:userActivity
restorationHandler:restorationHandler];
}
- (UIInterfaceOrientationMask)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window {
return [Orientation getOrientation];
}
- (void)pushRegistry:(PKPushRegistry *)registry didUpdatePushCredentials:(PKPushCredentials *)credentials forType:(PKPushType)type {
// Register VoIP push token (a property of PKPushCredentials) with server
[RNVoipPushNotificationManager didUpdatePushCredentials:credentials forType:(NSString *)type];
}
- (void)pushRegistry:(PKPushRegistry *)registry didInvalidatePushTokenForType:(PKPushType)type
{
// --- The system calls this method when a previously provided push token is no longer valid for use. No action is necessary on your part to reregister the push type. Instead, use this method to notify your server not to send push notifications using the matching push token.
}
- (void)pushRegistry:(PKPushRegistry *)registry didReceiveIncomingPushWithPayload:(PKPushPayload *)payload forType:(PKPushType)type withCompletionHandler:(void (^)(void))completion {
// --- NOTE: apple forced us to invoke callkit ASAP when we receive voip push
// --- see: react-native-callkeep
// --- Retrieve information from your voip push payload
// NSString *uuid = payload.dictionaryPayload[@"aps"][@"uuid"];
// NSString *callerName = [NSString stringWithFormat:@"%@ Calling from LuckyCalls", payload.dictionaryPayload[@"aps"][@"callerName"]];
// NSString *handle = payload.dictionaryPayload[@"aps"][@"handle"];
NSString *uuid = [[[NSUUID UUID] UUIDString] lowercaseString];
NSString *callerName = payload.dictionaryPayload[@"aps"][@"number"];
NSString *callType = payload.dictionaryPayload[@"aps"][@"type"];
NSString *handle = @"Calls";
BOOL hasVideo = [callType isEqualToString:@"video"] ? YES : NO;
// --- this is optional, only required if you want to call `completion()` on the js side
[RNVoipPushNotificationManager addCompletionHandler:uuid completionHandler:completion];
// --- Process the received push
[RNVoipPushNotificationManager didReceiveIncomingPushWithPayload:payload forType:(NSString *)type];
// NSDictionary *extra = [payload.dictionaryPayload valueForKeyPath:@"custom.path.to.data"];
[RNCallKeep reportNewIncomingCall: uuid
handle: handle
handleType: @"generic"
hasVideo: hasVideo
localizedCallerName: callerName
supportsHolding: YES
supportsDTMF: YES
supportsGrouping: YES
supportsUngrouping: YES
fromPushKit: YES
payload: nil
withCompletionHandler: completion];
// --- You don't need to call it if you stored `completion()` and will call it on the js side.
completion();
}
@end
Maybe I made a mistake in it
Can you please add console.log in useEffect just to see how many times you are attaching listeners. Also you can try to set breakpoints in place where this event is firing in xCode
one
Is that possible that you receive 2 voip push notifications? You should debug native objective-C with xCode
no, I checked it first, push is definitely 1
this is what the xcode log shows when the push comes
2024-01-11 17:37:39.556625+0200 LuckyCalls[693:111874] [native] [RNVoipPushNotificationManager] didReceiveIncomingPushWithPayload payload.dictionaryPayload = {
aps = {
alert = "Hello from APNs";
badge = 1;
callerName = Taras;
handle = 123123123;
uuid = 123;
};
uuid = "27858492-b209-4fb6-9359-825218a76a8b";
}, type = PKPushTypeVoIP
2024-01-11 17:37:39.556914+0200 LuckyCalls[693:111874] [RNCallKeep][reportNewIncomingCall] uuidString = 745ff3d3-fba9-4793-95f4-3dd3ff67a7c0
2024-01-11 17:37:39.557836+0200 LuckyCalls[693:112248] [native] [RNVoipPushNotificationManager] onVoipNotificationCompleted() not found. uuid = 27858492-b209-4fb6-9359-825218a76a8b
2024-01-11 17:37:39.582389+0200 LuckyCalls[693:111874] [RNCallKeep] sendEventWithNameWrapper: RNCallKeepDidDisplayIncomingCall, hasListeners : NO
2024-01-11 17:37:39.582461+0200 LuckyCalls[693:111874] [RNCallKeep][configureAudioSession] Activating audio session
2024-01-11 17:37:43.032228+0200 LuckyCalls[693:111874] [EventDispatcher] Found no UIEvent for backing event of type: 11; contextId: 0xE23307E5
2024-01-11 17:37:43.032572+0200 LuckyCalls[693:111874] [EventDispatcher] Found no UIEvent for backing event of type: 11; contextId: 0xE23307E5
2024-01-11 17:37:43.036057+0200 LuckyCalls[693:111874] [EventDispatcher] Found no UIEvent for backing event of type: 11; contextId: 0xE23307E5
2024-01-11 17:37:44.789032+0200 LuckyCalls[693:111874] [RNCallKeep][CXProviderDelegate][provider:performEndCallAction]
2024-01-11 17:37:44.789161+0200 LuckyCalls[693:111874] [RNCallKeep] sendEventWithNameWrapper: RNCallKeepPerformEndCallAction, hasListeners : NO
2024-01-11 17:37:45.847577+0200 LuckyCalls[693:111874] [RNCallKeep][CXProviderDelegate][provider:performEndCallAction]
2024-01-11 17:37:45.847780+0200 LuckyCalls[693:111874] [RNCallKeep] sendEventWithNameWrapper: RNCallKeepPerformEndCallAction, hasListeners : NO
2024-01-11 17:37:46.006107+0200 LuckyCalls[693:111874] [native] Sending `RNCallKeepDidChangeAudioRoute` with no listeners registered.
2024-01-11 17:37:46.006450+0200 LuckyCalls[693:112253] [javascript] Sending `RNCallKeepDidChangeAudioRoute` with no listeners registered.
So yeah it is coming from native part - [RNCallKeep][CXProviderDelegate][provider:performEndCallAction]
x 2
You can try my older forked version that works for me even nowadays. Or try to fix in the lib and then patch it.
https://github.com/Romick2005/react-native-voip-push-notification
I recently was doing some get voip code refactor and I think I know what is your problem. It is because you call voip registration twice: from native code and from js.
Native:
[RNVoipPushNotificationManager voipRegistration];
JS:
VoipPushNotification.registerVoipToken(); // --- register token
So I suggest to call voip registration only on native side and using delayed events from didLoadWithEvents you can get registration voip token on JS side.
HI, this library using VOIP call for react native app? if i use this mean,can i get voip token and open call kit everything .
Yeah, this lib is just to get voip token, that would be used for iOS CallKit.
I have the following code in app.js
when push comes i get two calls Alert.alert('Call answer');
What could be the problem?