NFC Scan prompt an application selection window - xamarin.forms

My app is made in Xamarin Forms. I have just compiled my application with the Android 31 SDK, and when the application launches on a smartphone on Android 13, the NFC reading process shows me a window to select the application that can read the nfc tag.On other versions of android I do not have this window that appears.
The permissions included in the manifest :
<uses-permission android:name="android.permission.NFC" />
<uses-permission android:name="android.permission.BIND_NFC_SERVICE" />
<uses-permission android:name="android.permission.NFC_TRANSACTION_EVENT" />
And the code to declare listening :
var intent = new Intent(this, this.GetType()).AddFlags(ActivityFlags.SingleTop);
this.NFCdevice.EnableForegroundDispatch(
this,
PendingIntent.GetActivity(this, 0, intent, 0),
new[] { new IntentFilter(NfcAdapter.ActionTechDiscovered) },
new[]
{
new[] { NFCTechs.Ndef }, new[] { NFCTechs.MifareClassic }, new[] { NFCTechs.MifareUltralight },
new[] { NFCTechs.NdefFormatable }, new[] { NFCTechs.NfcA }
});
If someone has an idea.
I tried to add the NFC in the requirements of the application :
[assembly: UsesFeature("android.hardware.nfc", Required = true)]
I also added these formats :
NFCTechs.NfcB, NFCTechs.NfcF, NFCTechs.NfcV

Related

Firebase Dynamic Links doesn't navigate to deep link on iOS

Using Firebase Dynamic Links in a Managed Workflow Expo app directs to the correct deep link in the app on Android, but on iOS only opens the app in either whatever page was last open or the homepage.
app.config.js
ios: {
associatedDomains: [
'applinks:*.myapp.web.app',
'applinks:myapp.web.app',
'applinks:*.myapp.page.link',
'applinks:myapp.page.link',
],
},
AppNavigation.js
const linking = {
prefixes: [
prefix,
'https://myapp.web.app',
'https://*.myapp.web.app',
],
The apple-app-site-association file stored on myapp.web.app
{
"applinks": {
"apps": [],
"details": [
{
"appID": "1234567890.com.my.app",
"paths": [ "*" ]
}
]
}
}
The Dynamic Link is generated using REST API with the following payload:
const payload = {
dynamicLinkInfo: {
domainUriPrefix: 'https://myapp.page.link',
link: `https://myapp.web.app/${deepLink}`,
androidInfo: {
androidPackageName: com.my.app,
},
iosInfo: {
iosBundleId: com.my.app,
iosAppStoreId: 1234567890,
},
The generated Dynamic Link opens the app and directs to the ${deepLink} on Android as expected, but not on iOS. This was tested in an app built with EAS built.
Ended up solving this myself. Dynamic Links get resolved (converted from short link to full link) automatically on Android, but on iOS this has to be done manually with dynamicLinks().resolveLink(url);
After resolving, the link gets picked up by React Native Navigation and works like a normal deep link.
Full code for Dynamic Links:
const linking = {
prefixes: [
'https://myapp.page.link',
'https://myapp.web.app',
],
async getInitialURL() {
// If the app was opened with a Firebase Dynamic Link
const dynamicLink = await dynamicLinks().getInitialLink();
if (dynamicLink) {
const { url } = dynamicLink;
const resolvedLink = await dynamicLinks().resolveLink(url);
return resolvedLink.url;
}
// If the app was opened with any other link (sometimes the Dynamic Link also ends up here, so it needs to be resolved
const initialUrl = await Linking.getInitialURL();
if (initialUrl) {
const resolvedLink = await dynamicLinks().resolveLink(initialUrl);
return (resolvedLink) ? resolvedLink.url : initialUrl;
}
},
subscribe(listener) {
const handleDynamicLink = (dynamicLink) => {
listener(dynamicLink.url);
};
// Listen to incoming links from deep linking
const unsubscribeToDynamicLinks = dynamicLinks().onLink(handleDynamicLink);
return () => {
// Clean up the event listeners
unsubscribeToDynamicLinks();
};
},
};
In my case I also had to install all 3 of the following libraries:
"#react-native-firebase/analytics": "16.4.3",
"#react-native-firebase/app": "16.4.3",
"#react-native-firebase/dynamic-links": "16.4.3",

Xamarin.Forms AVPlayer exit fullscreen from method

I have a Xamarin application which plays a video for 30 seconds and then shows a dialog. The user can continue to watch (dismiss the dialog) or click an action in the dialog (which then should close full-screen and navigate elsewhere in the app).
I have this working on the simulator. However, when I run the following code on an real iOS device, the app crashes without any stacktrace.
ViewModel.cs
var openLink = await _userDialogs.ConfirmAsync("...", cancelText: "Dismiss", okText: "Yes");
if (openLink)
{
await _navigationService.Close(scope);
MessagingCenter.Send(Application.Current, "CloseFullscreen");
}
VideoRenderer.cs
_playerViewController = new AVPlayerViewController()
{
ExitsFullScreenWhenPlaybackEnds = true
};
player = new AVPlayer();
_playerViewController.Player = player;
...
SetNativeControl(_playerViewController.View);
MessagingCenter.Subscribe<Xamarin.Forms.Application>(this, "CloseFullscreen", (app) =>
{
BeginInvokeOnMainThread(() =>
{
var selectorName = "exitFullScreenAnimated:completionHandler:";
var selector = new ObjCRuntime.Selector(selectorName);
if (_playerViewController.RespondsToSelector(selector))
_playerViewController.PerformSelector(selector, NSObject.FromObject(true), 0);
});
});
Please note that I am not using the CrossMediaManager plugin due to this bug: https://github.com/Baseflow/XamarinMediaManager/issues/629

React Native Firebase 6 cloud messaging and Push notifications

I'm working with react native and firebase 6 to send push notifications.
I use the official documentations of the new version :
https://invertase.io/oss/react-native-firebase/v6
I add native code for both android and ios to handle sending and receiving notifications
In my AndroidManifest.xml :
<!-- [START firebase_service] -->
<service
android:name=".java.MyFirebaseMessagingService"
android:exported="false">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
</service>
<!-- [END firebase_service] -->
I did not create the MyFirebaseMessagingService .
I AppDelegate.m i add some functions :
// Required for the register event.
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
{
[FIRMessaging messaging].APNSToken = deviceToken;
[RNCPushNotificationIOS didRegisterForRemoteNotificationsWithDeviceToken:deviceToken];
NSLog(#"APNs device token retrieved: %#", deviceToken);
}
// Required for the registrationError event.
- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error
{
[RNCPushNotificationIOS didFailToRegisterForRemoteNotificationsWithError:error];
NSLog(#"Unable to register for remote notifications: %#", error);
}
// Required for the localNotification event.
- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification
{
[RNCPushNotificationIOS didReceiveLocalNotification:notification];
}
In my Component.js i get the token like this :
// Firebase
import firebase from '#react-native-firebase/app'
import messaging from '#react-native-firebase/messaging'
// ----- COMPONENT DID MOUNT ---- //
async componentDidMount () {
// ====================================================== //
// ====================================================== //
// ====================================================== //
const granted = messaging().requestPermission()
if (granted) {
console.log('User granted messaging permissions!')
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //
firebase
.messaging()
.getToken()
.then(fcmToken => {
if (fcmToken) {
// user has a device token
console.log('-------- FCM TOKEN -------')
console.log(fcmToken)
console.log(JSON.stringify(fcmToken))
this._setItem(fcmToken)
} else {
// user doesn't have a device token yet
console.log('error')
}
})
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //
} else {
console.log('User declined messaging permissions :(')
}
// ====================================================== //
// ====================================================== //
// ====================================================== //
}
// ----- FIN COMPONENT DID MOUNT ---- //
I send POST request to https://fcm.googleapis.com/fcm/send :
{
"to" : "token",
"notification" : {
"body" : "un nouveau partage",
"title" : "un partage de contact reçu",
"priority" : "high",
"vibration":true,
"sound": "Enabled",
"badge":1,
"requireInteraction": true,
"click_action": "fcm.ACTION.HELLO"
},
"data" : {
"body" : "nouvelle opportunité",
"title" : "un nouveau partage",
"content_available" : true,
"priority" : "high"
}
}
I receive the notification for both android and ios but i can't handle the click action :
I want to redirect to specific route when the user click on the notification .
I haven't used Firebase for notifications, but as you're saying the notifications are working, then the actual issue it seems to me is you want to handle it when your app opens.
So here are the steps you have to follow to get your work done.
Get the data coming in the notification, on the event onNotificationOpened. Check out this link to check if you're getting the notification data.
Next, you want to a specific route on the basis of notification. What I do is, send the type of the screen and id related to that screen to navigate there, ex:
{
"entity": "Place",
"id": "123"
}
So, when I receive the notification, I send the data to a switch case factory that navigate to the screen on the basis of info in that data. Something like that.
function navigateToScreen(entity:string, id:string){
let screenName = "";
let params = {}
switch(entity){
case "Place":
screenName = "placeScreen";
params = {id};
break;
default: return;
}
// Navigation Service = https://reactnavigation.org/docs/navigating-without-navigation-prop/
NavigationService.navigate(screenName, params);
}
Now in case you want to run a specific function on the basis of notification, you can do it on the basis of info received. Like in this example I have to make an API req to get the data of that place by id.
const id = props.match.params['id'];
useEffect(() => {
getThePlaceDetails(id);
}, [id]);

Clevertap for IONIC push notification not working for IOS

I have built an app using IONIC 1 and using clevertap for analytics and push notification. I am using an official cordova plugin to consume CLEVERTAP push notifications,
CleverTap Cordova Plugin
For android it is working fine but for IOS it is not working. Can anyone help me with this?
Here the sample initialization code,
var app = {
initialize: function() {
this.bindEvents();
},
bindEvents: function() {
document.addEventListener('deviceready', this.onDeviceReady, false);
document.addEventListener('onCleverTapProfileSync', this.onCleverTapProfileSync, false);
document.addEventListener('onCleverTapProfileDidInitialize', this.onCleverTapProfileDidInitialize, false);
document.addEventListener('onCleverTapInAppNotificationDismissed', this.onCleverTapInAppNotificationDismissed, false);
document.addEventListener('onDeepLink', this.onDeepLink, false);
document.addEventListener('onPushNotification', this.onPushNotification, false);
},
onDeviceReady: function() {
app.receivedEvent('deviceready');
$rootScope.CleverTap = CleverTap;
CleverTap.notifyDeviceReady();
CleverTap.registerPush();
},
onCleverTapProfileSync: function(e) {
console.log(e.updates);
},
onCleverTapProfileDidInitialize: function(e) {
console.log(e.CleverTapID);
},
onCleverTapInAppNotificationDismissed: function(e) {
console.log(e.extras);
console.log(e.actionExtras);
},
onDeepLink: function(e) {
console.log(e.deeplink);
},
onPushNotification: function(e) {
console.log(JSON.stringify(e.notification));
},
receivedEvent: function(id) {
var parentElement = document.getElementById(id);
console.log('parseElement', parentElement, id);
var listeningElement = parentElement.querySelector('.listening');
var receivedElement = parentElement.querySelector('.received');
listeningElement.setAttribute('style', 'display:none;');
receivedElement.setAttribute('style', 'display:block;');
console.log('Received Event: ' + id);
}};app.initialize();
For setting up push notifications for iOS you need to follow the steps given in the below link to setup your Apple certificates -
Setting Up Push Notifications for your app
If you plan on using deep links, check the following link -
Setting up deep links
And then from your Javascript file, use the following code to push the APNs token to CleverTap -
CleverTap.registerPush();
Let me know if this was useful to you. If you have more questions or concerns you can always reach out to CleverTap support team at support#clevertap.com

push notification does not work for ios and azure with specific token

We are using Visual Studio to create an Apache Cordova app that is connected to an Azure Mobile Service . We are using the Cordova Push Plugin to receive Notifications in our app. We have created a JavaScript method in the Azure Mobile Service to send the notifications, this method is triggered by a scheduler. Please note that the intention is to send each Notification to a particular device.
The notifications work perfectly for Android devices but not for the iOS devices.
In iOS the notification is not received however the method in Azure Mobile Service always returns “Success”.
If we set the Device Token to "Null" , then it works for iOS devices (but sends to all devices not just one).
Could anyone please help us to resolve this issue?
this is Push.Send() method in Azure
push.send(result.DeviceID, payload, {
success: function(pushResponse){
//console.log("Sent push:", pushResponse);
//update notification sent time-start
var sqlUpdate = '';
mssql.query(sqlUpdate, {
success: function(results)
{
//response.json(statusCodes.OK, results);
},
error : function()
{
//response.send(statusCodes.INTERNAL_SERVER_ERROR);
}
})
//update notification sent time-end
},
error: function (pushResponse) {
//console.log("Error Sending push:", pushResponse);
}
});
and this is my App registration Method in the app
var pushNotification = window.plugins.pushNotification;
//alert("device.platform" + device.platform);
// Platform-specific registrations.
if (device.platform == 'android' || device.platform == 'Android') {
alert("device.platform : Android ");
// Register with GCM for Android apps.
pushNotification.register(
app.successHandler, app.errorHandler,
{
"senderID": GCM_SENDER_ID,
"ecb": "app.onNotificationGCM"
});
} else if (device.platform === 'iOS') {
// Register with APNS for iOS apps.
alert("device.platform : iOS ");
pushNotification.register(
app.tokenHandler,
app.errorHandler, {
"badge":"true",
"sound":"true",
"alert":"true",
"ecb": "app.onNotificationAPN"
});
}
else if(device.platform === "Win32NT"){
// Register with MPNS for WP8 apps.
alert("Device platform Windows")
pushNotification.register(
app.channelHandler,
app.errorHandler,
{
"channelName": "MyPushChannel",
"ecb": "app.onNotificationWP8",
"uccb": "app.channelHandler",
"errcb": "app.ErrorHandler"
});
}
// #endregion notifications-registration

Resources