ionic react local notifications with capacitor not working - ionic-framework

I am trying to implement local notifications using capacitor.
first I installed plugin using below commands,
npm install #ionic-native/local-notifications
npm install cordova-plugin-local-notification
Then in my .js file, I did add below code
import { Plugins } from '#capacitor/core';
And
scheduleNotification = () => {
Plugins.LocalNotifications.schedule({
notifications: [
{
title: "Title",
body: "Body",
id: 1,
schedule: { at: new Date(Date.now() + 1000 * 5) },
sound: null,
attachments: null,
actionTypeId: "",
extra: null
}
]
});
console.log('scheduled notifications');
}
I tried everything, but I can't see any local notification on my iPhone 6s running iOS 12.
When I check Xcode logs, I can see Scheduled notification with id 1.
cordova-plugin-badge (0.8.8)
cordova-plugin-device (2.0.3)
cordova-plugin-local-notification (0.9.0-beta.2)

I had the same issue, I set my notification id with an UUID but it did not work. I solved it in setting my notification id with new Date().getTime().

It was issue regarding id pass in your result.
PushNotifications.addListener('pushNotificationReceived',
async (notification: any) => {
console.log(notification);
const notifs = await LocalNotifications.schedule({
notifications: [
{
title: notification.title,
body: notification.body,
id: new Date().getTime(),
schedule: { at: new Date(Date.now() + 1000 * 5) },
sound: this.platform.is("android")
? "file://sound.mp3"
: "file://beep.caf",
attachments: null,
actionTypeId: "",
extra: notification
}
]
});
}
);

For the ios, I think, it is not supported yet.
For android, try to request permission.

Related

OneSignal issue for Ionic 6 & Capacitor

I'm trying to set OneSignal for push notifications on devices.
I did the step by step to setup methods which are shown in the OneSignal Documentation, but no luck.
I also did the official Ionic - Capacitor - Cordova methods to setup OneSignal, with no luck again.
This is the first method I did, following Ionic official Docs:
app.module.ts
...
import { OneSignal } from '#awesome-cordova-plugins/onesingal';
#NgModule({
...
providers: [OneSignal]
});
I created a PushService where I include methods from OneSignal.
push.service.ts:
import { OneSignal } '#awesome-cordova-plugins/onesignal';
export class PushService {
constructor ( private signal: OneSignal ) {}
start (): void {
this.signal.startInit ( 'MY_ONESIGNAL_APP_ID', 'FIREBASE_ID' );
this.signal.handleNotificationReceived().subscribe(() => {
// do something when notification is received
});
...
this.signal.endInit();
}
}
I call "start" method on my app.component.ts, initializing on this.platform.ready...
And when I test on my device, the answer from debug is "plugin_not_installed" OneSignal
Second method I use, following instructions from the Official OneSignal Docs "Ionic & Capacitor"
Directly I put methods on my "start" in push.service.ts, I didn't call it on app.module.ts because is a function:
import { OneSignal } from 'onesignal-cordova-plugin';
export class PushService {
constructor () {}
start (): void {
OneSignal.setAppId ( 'ONESIGNAL_APP_ID' );
...
OneSignal.setNotificationWillShowInForegroundHandler ( ( d ) => console.log ( d ) );
}
}
In this case, the error is "TypeError: Cannot read properties of undefined (reading 'setAppId')"
So, any of those methods is not working.
My system info develop is:
Ionic:
Ionic CLI : 6.18.1 (C:\Users\user\AppData\Roaming\npm\node_modules\#ionic\cli)
Ionic Framework : #ionic/angular 6.0.1
#angular-devkit/build-angular : 13.1.2
#angular-devkit/schematics : 12.2.13
#angular/cli : 13.1.2
#ionic/angular-toolkit : 5.0.3
Capacitor:
Capacitor CLI : 3.3.3
#capacitor/android : 3.3.3
#capacitor/core : 3.3.3
#capacitor/ios : not installed
Utility:
cordova-res : not installed globally
native-run : 1.5.0
System:
NodeJS : v16.13.1 (C:\Program Files\nodejs\node.exe)
npm : 8.2.0
OS : Windows 10
I think you need to install the plugin - this is what I have in package.json
"onesignal-cordova-plugin": "^3.0.1"
And import like this -
import OneSignal from 'onesignal-cordova-plugin';
And also in angular.json add this part with allowedCommonJsDependencies
{
"projects": {
"app": {
"root": "",
"sourceRoot": "src",
"projectType": "application",
"prefix": "app",
"schematics": {},
"architect": {
"build": {
"builder": "#angular-devkit/build-angular:browser",
"options": {
"allowedCommonJsDependencies": [
"onesignal-cordova-plugin"
]
}
}
}
}
}
}
The official One Signal docs need improvement but they helped me to find the path to get push notifications working with Capacitor 3 and Ionic 6 using Vue on web mobile and also on Android. This is working on my projects.
The points of attention are these:
If you'll use mobile push or native push, you have to initialize Onesignal detecting the platform.
You also have to include Onesignal service worker js files somewhere they could be located by the browser.
// Call this function when your app start
function OneSignalInit() {
OneSignal.setAppId("xxxxx-xxxxxx-xxxxxx"); //Your APP ID
OneSignal.setNotificationOpenedHandler(function(jsonData) {
console.log('notificationOpenedCallback: ' + JSON.stringify(jsonData));
});
OneSignal.promptForPushNotificationsWithUserResponse(function(accepted) {
console.log("User accepted notifications: " + accepted);
});
}
if (getPlatforms().includes("capacitor")) {
OneSignalInit();
} else {
window.OneSignal = window.OneSignal || [];
window.OneSignal.push(function () {
// You have to include some JS files from Onesignal as the docs say to do
// Place them in a place findable by the browser when the URL is resolved
window.OneSignal.SERVICE_WORKER_PARAM = { scope: '/assets/js/onesignal/' };
window.OneSignal.SERVICE_WORKER_PATH = 'assets/js/onesignal/OneSignalSDKWorker.js'
window.OneSignal.SERVICE_WORKER_UPDATER_PATH = 'assets/js/onesignal/OneSignalSDKUpdaterWorker.js'
window.OneSignal.init({
appId: "xxxxx-xxxxx-xxxxx", //Your APP ID
safari_web_id: "web.onesignal.auto.xxxxxxxxxxx",
notifyButton: {
enable: false,
},
subdomainName: "odontoenlace",
promptOptions: {
slidedown: {
prompts: [
{
type: "push", // current types are "push" & "category"
autoPrompt: true,
text: {
/* limited to 90 characters */
actionMessage: "Nos gustaría enviarte notificaciones para que estés al tanto de eventos en tu perfil.",
/* acceptButton limited to 15 characters */
acceptButton: "Aceptar",
/* cancelButton limited to 15 characters */
cancelButton: "Cancelar"
},
delay: {
pageViews: 0,
timeDelay: 1
}
}
]
}
}
});
});
}
After all that, you can use this code to detect if Onesignal is recognized and get your Onesignal user_id also known as player_id. Again, checking if you are on web or native.
if (getPlatforms().includes("capacitor")) {
OneSignal.setAppId("xxxxx-xxxxx-xxxxxx"); // Your APP ID
OneSignal.getDeviceState((stateChanges) => {
console.log(
"OneSignal getDeviceState: " + JSON.stringify(stateChanges)
);
if (stateChanges && stateChanges.hasNotificationPermission) {
console.log("Player ID: " + stateChanges.userId);
} else {
console.log("Push notifications are disabled");
}
});
} else {
console.log("Platform is not capacitor");
is_push_supported.value =
window.OneSignal.isPushNotificationsSupported();
if (is_push_supported.value) {
if (!getPlatforms().includes("capacitor")) {
window.OneSignal.getUserId((userId) => {
console.log("Player ID: " + userId);
});
}
}
}
Finally, if you're compiling your app, Capacitor's default settings for release mode, suppress externals Onesignal libraries so check on your build.gradle file that you have disabled proguard, and minifyEnabled is set to false. The best way is to leave empty the relase object
buildTypes {
release {
}
}

Nuxt.js - Implementing a component using Plugin

I would like to implement a custom Toaster component into my NuxtJs application by this method this.$toast.show({}) What is the best way of approaching this? Sadly I can't find any documentation on this.
Sorry, I arrive one year late...
I had the same proplem. Here is my code:
The index of my plugin (index.js ; Nofification.vue is a classical Vue component):
import Notifications from './Notifications.vue'
const NotificationStore = {
state: [], // here the notifications will be added
settings: {
overlap: false,
horizontalAlign: 'center',
type: 'info',
timeout: 5000,
...
},
setOptions(options) {
this.settings = Object.assign(this.settings, options)
},
removeNotification(timestamp) {
...
},
addNotification(notification) {
...
},
notify(notification) {
...
},
}
const NotificationsPlugin = {
install(Vue, options) {
const app = new Vue({
data: {
notificationStore: NotificationStore,
},
methods: {
notify(notification) {
this.notificationStore.notify(notification)
},
},
})
Vue.prototype.$notify = app.notify
Vue.notify = app.notify
Vue.prototype.$notifications = app.notificationStore
Vue.component('Notifications', Notifications)
if (options) {
NotificationStore.setOptions(options)
}
},
}
export default NotificationsPlugin
Here I call my plugin and inject it in Nuxt:
import Notifications from '~/components/NotificationPlugin'
Vue.use(Notifications)
export default (context, inject) => {
inject('notify', Vue.notify)
}
In my case, I use it in another plugin (nuxtjs axios).
import NOTIFICATIONS from '~/constants/notifications'
export default function ({ error, $axios, app }) {
// Using few axios helpers (https://axios.nuxtjs.org/helpers):
$axios.onError((axiosError) => {
// eslint-disable-next-line no-console
console.log('Axios: An error occured! ', axiosError, axiosError.response)
if (process.server) {
...
} else {
app.$notify({
message: 'Mon message',
timeout: NOTIFICATIONS.DEFAULT_TIMEOUT,
icon: 'tim-icons icon-spaceship',
horizontalAlign: NOTIFICATIONS.DEFAULT_ALIGN_HORIZONTAL,
verticalAlign: NOTIFICATIONS.DEFAULT_ALIGN_VERTICAL,
type: 'success',
})
console.log('PRINT ERROR')
return Promise.resolve(true)
}
})
}
As I injected it, I think I could have done export default function ({ error, $axios, app, $notify }) { and directly use $notify (and not the app.$notify).
If you want a better understanding, feel free to consult #nuxtjs/toast which works the same way:
https://github.com/nuxt-community/community-modules/blob/master/packages/toast/plugin.js
And the matching Vue component:
https://github.com/shakee93/vue-toasted/blob/master/src/index.js
Good luck, this is not easy stuff. I'll try to add something easier to understand in the docs!
you can find in this package https://www.npmjs.com/package/vue-toasted
installation
npm install vue-toasted --save
make a file as name toast.js in plugin folder
toast.js
import Vue from 'vue';
import Toasted from 'vue-toasted';
Vue.use(Toasted)
add this plugin to nuxt.config.js
plugins: [
{ src: '~/plugins/toast', ssr: false },
],
now you able to use in your methods like this
this.$toasted.show('hello i am your toast')
hope this helps

cordova-plugin-iosrtc not work with sip.js 0.11 on movile ionic js webrtc app

I am developing a webrtc call/videocall app bases on Ionic/AngularJS technologies. The app works with sip.js for call actions over PBX server. For IOS integration with WebRtc, app works with cordova-plugin-iosrtc. When I try connect with PBX to call or received call, app throws errors on two possible use mode of cordova-plugin-iosrtc with sip.js
A) When I try to use cordova-plugin-iosrtc working on peer connection iOS plugin mode ....
telephoneService.js (Angular JS)
var pc = new cordova.plugins.iosrtc.RTCPeerConnection({
iceServers: []
});
cordova.plugins.iosrtc.getUserMedia(
// constraints
{ audio: true, video: true },
// success callback
function (stream) {
console.log('got local MediaStream: ', stream);
pc.addStream(stream);
},
// failure callback
function (error) {
console.error('getUserMedia failed: ', error);
}
);
var sessionDescriptionHandlerOptions = {
constraints: {
audio: audioId,
video: videoId
},
media: {
local: {
audio: document.getElementById('localAudio')
},
remote: {
audio: document.getElementById('remoteAudio')
}
},
extraHeaders: extraHeaders
}
}
userAgent.invite('sipusertocall', sessionDescriptionHandlerOptions);
receive the next error:
undefined is not a object evaluating 'environment.navigator.mediaDevices.getUserMedia' (sip.js lib)
B)
cordova.plugins.iosrtc.registerGlobals(); use iosrtc plugin with webrtc native api (navigator.mediaDevice.getUserMedia(), ....)
navigator.mediaDevices.getUserMedia(
function (stream) {
console.log('got local MediaStream: ', stream);
window.stream = stream;
},
// failure callback
function (error) {
console.error('getUserMedia failed: ', error);
}
)
var sessionDescriptionHandlerOptions = {
constraints: {
audio: audioId,
video: videoId
},
media: {
local: {
audio: document.getElementById('localAudio')
},
remote: {
audio: document.getElementById('remoteAudio')
}
},
extraHeaders: extraHeaders
}
userAgent.invite('sipusertocall', sessionDescriptionHandlerOptions);
App receive from sip.js next error from PBX: Failed:WebRTC Error
Client show next error at same time:
setLocalDescription() must be called with a RTCSessionDescription instance as first argument
So the newer SIP.js is actually passing in an instance of RTCSessionDescriptionInit which although has a similar structure: { sdp: ..., type: ... } to an RTCSessionDescription init is not accepted by the cordova iosrtc implementation.
I have created a fix for this in the form of a custom SDH for SIP.js (as I encountered the exact same issue). My custom SDH converts the object to a new RTCSessionDescription(...) just before it gets passed in to getLocationDescription and setRemoteDescription.
Link to SDH plugin:
https://github.com/iotum/cordova-ios-session-description-handler
Hope this helps!
Wes

No vibrate in flutter notifications

I am using firebase cloud functions to send a notification to a particular user. This is the payload that I am sending from the functions.
var payload = {
notification: {
sound: "default",
color: "#ff3296fa",
vibrate: "300",
priority: 'high',
notificationType: "52",
title: titleToBeShown,
body: message['message'],
icon: 'ic_launcher',
},
data: {
click_action: 'FLUTTER_NOTIFICATION_CLICK',
channelId: channelID,
channelName: channelName,
channelType: channelType
},
};
I am using firebase_messaging (flutter package: https://pub.dartlang.org/packages/firebase_messaging) to receive the notifications and I have written the codes for onMessage, onLaunch and onResume methods.
So when I send a message using Admin SDK admin.messaging().sendToDevice(token, payload), it sends it without vibration and sound. How can I add vibration and sound to it? Right now, it feels like a silent notification then. Which will easily be ignored by the users. Both in android and ios, its the same problem.
The sound field does not go in the notification object. It belongs in the android and apns objects. Your payload should look like this:
var payload = {
data: {
channelId: channelID,
channelName: channelName,
channelType: channelType
},
android: {
priority: 'high',
notification: {
title: titleToBeShown,
body: message['message'],
icon: 'ic_launcher',
sound: 'default',
color: '#ff3296fa',
clickAction: 'FLUTTER_NOTIFICATION_CLICK',
// Not sure what this is supposed to be, but not a valid parameter
notificationType: '52',
},
},
apns: { ... }
};
I've filled in the Android fields, but I'm not familiar with APNS payloads. Check out the FCM documentation here for more details and you can see the available payload options for APNS here.

Change FCM sender ID

I had setup push notification in my App using the following command:
ionic cordova plugin add phonegap-plugin-push --variable SENDER_ID="1234567890"
Which added the below code to my package.json
"phonegap-plugin-push": {
"SENDER_ID": "1234567890"
}
Now the issue is I have to change this sender ID to something else and I want to know how to do this, also I have the below code in my project to set up the options for push notification.
const options: PushOptions = {
android: {
senderID: '218580369028'
},
ios: {
alert: 'true',
badge: true,
sound: 'false'
},
windows: {},
browser: {
pushServiceURL: 'http://push.api.phonegap.com/v1/push'
}
};
Is this as simple as just replacing the sender ID with what I want in package.json and in the above code. Or do I have to do something else for this. Any help is greatly appreciated.