I am trying to create a button that onClick, runs a client-side script(myFunction();) to connect to a Bluetooth device through Chrome.
However, it returns the following error:
SecurityError: requestDevice() called from cross-origin iframe.
The code to request the Bluetooth is as follows:
/* jshint esnext:true */
function myFunction() {
navigator.bluetooth.requestDevice({ filters: [{ services: ['heart_rate'] }] })
.then(device => { /* ... */ })
.catch(error => { console.log(error); });
}
Related
i'm unable to open a link using window.open whithin a http request.
Here is how i tried:
const config = {
headers: {token: this.apiKey, authtoken: token},
};
const url = `https://api.eatsmartapp.de/delivery/users/receipt?id=${this.orderId}`;
// #ts-ignore
this.http.get<any>(url, config).subscribe(dataset => {
window.open('link', '_blank');
}, error => {
});
If i try to open the link outside the subscription area its working fine but if i try to open it in my subscription, nothing is happening on my mobile device
Try using window as a service. In your module.ts file
providers: [
{ provide: Window, useValue: window }
]
Then in your component.ts, or wherever
constructor(private window: Window) {
// ...
}
in which case your window.open would be like
this.http.get<any>(url, config).subscribe(dataset => {
this.window.open(dataset.url, '_blank');
}
I have an Ionic 4 app which I have integrated with Firebase for authentication etc. I want to implement Firebase's cloud messaging so I can push messages to my app on both Android and iOS. I have done this pretty easily on iOS and I have sent a message via Postman which shows on my iPhone and I see the JSON of the message I have sent. When I try it on Android it doesn't work. Both devices receive the message but handle it very diferently.
I have read in a lot of places that you need to set the click_action to FCM_PLUGIN_ACTIVITY but when I do that the app doesn't even open on Android. When I take it out the app loads when you click the message but it doesn't show the body of the message like on iOS in my alert.
import { FCM } from '#ionic-native/fcm/ngx';
...
constructor(public platform: Platform, public fcm: FCM)
...
this.platform.ready().then(() => {
this.fcm.onNotification().subscribe(data => {
alert(JSON.stringify(data));
});
this.fcm.onTokenRefresh().subscribe(token => {
// Register your new token in your back-end if you want
// backend.registerToken(token);
});
}).catch((error) => {
this.showFailureMessage(error.message);
});
This is what I am posting off to... https://fcm.googleapis.com/fcm/send
{
"notification":{
"title":"My Title",
"body":"My Body",
"sound":"default",
"click_action":"FCM_PLUGIN_ACTIVITY"
"icon":"fcm_push_icon",
},
"data":{
"type":"Something",
},
"to":"/topics/all",
"priority":"high",
"restricted_package_name":""
}
Any help would be very much appreciated.
You seem to be missing the data.wasTapped part in your subscribe. Here, try this:
this.fcm.onNotification().subscribe(data => {
if (data.wasTapped) {
alert('Received in background');
alert(JSON.stringify(data));
} else {
alert('Received in foreground');
alert(JSON.stringify(data));
}
});
I'm having difficulty invoking a login method, it follows
$ meteor list
Accounts-base 1.2.14 A user account system
Ecmascript 0.6.1 Compiler plugin that supports ES2015 + in all .js files
Meteor-base 1.0.4 Packages that every Meteor app needs
React 15.0.1 Everything you need to use React with Meteor.
Static-html 1.1.13 Defines static page content in .html files
/server/main.js
import { Accounts } from 'meteor/accounts-base'
Accounts.registerLoginHandler('simples', (ttt) => {
console.log(ttt);
});
/client/main.js
autenticar(){
Accounts.callLoginMethod({
methodName: 'simples',
methodArguments: [{ tipo : 'simples' }],
validateResult: function (result) {
console.log('result', result);
},
userCallback: function(error) {
if (error) {
console.log('error', error);
}
}
})
}
When calling authenticar(), I get this error:
errorClass
Details: undefined
Error: 404
ErrorType: "Meteor.Error"
Message: "Method 'simples' not found [404]"
Reason: "Method 'simples' not found"
Where is the error?
I've never used this API personally, but from a quick glance through the Meteor internals, I see a couple issues.
Accounts.registerLoginHandler only adds an additional handler to an array of built-in handlers which are called as part of the default Meteor login process.
If you are trying to plug in an additional handler into the existing process, you should call Accounts.callLoginMethod without the methodName key.
Calling Accounts.callLoginMethod with methodName will bypass the built-in handlers completely and replace them with your custom method, however this method needs to be declared separately by you with Meteor.methods, not registerLoginHandler.
So, that's probably your error -- you need to define your simples method with Meteor.methods. Also, you should check the code for the requirements of this method, see the comments in the code here:
https://github.com/meteor/meteor/blob/devel/packages/accounts-base/accounts_client.js
Only to complement and keep as a referral for someone else to get here. That way it's working
client.js
Accounts.callLoginMethod({
methodArguments: [{tipo: 'simples'}],
validateResult: (result) => {
console.log('success', result);
},
userCallback: function(error) {
if (error) {
console.log('error', error);
}
}
});
server.js
Meteor.startup(function () {
var config = Accounts.loginServiceConfiguration.findOne({
service : 'simples'
});
if (!config) {
Accounts.loginServiceConfiguration.insert({ service: 'simples' });
}
});
Accounts.registerLoginHandler((opts) => {
if(opts.tipo === 'simples'){
return Accounts.updateOrCreateUserFromExternalService ('simples', {
id: 0 // need define something
}, {
options : 'optional'
})
}
});
I'm using Firebase Cloud Messaging + Service worker to handle background push notifications.
When the notification (which contains some data + a URL) is clicked, I want to either:
Focus the window if it's already on the desired URL
Navigate to the URL and focus it if there is already an active tab open
Open a new window to the URL if neither of the above conditions are met
Points 1 and 3 work with the below SW code.
For some reason point #2 isn't working. The client.navigate() promise is being rejected with:
Uncaught (in promise) TypeError: Cannot navigate to URL: http://localhost:4200/tasks/-KMcCHZdQ2YKCgTA4ddd
I thought it might be due to a lack of https, but from my reading it appears as though localhost is whitelisted while developing with SW.
firebase-messaging-sw.js:
// Give the service worker access to Firebase Messaging.
// Note that you can only use Firebase Messaging here, other Firebase libraries
// are not available in the service worker.
importScripts('https://www.gstatic.com/firebasejs/3.5.3/firebase-app.js');
importScripts('https://www.gstatic.com/firebasejs/3.5.3/firebase-messaging.js');
// Initialize the Firebase app in the service worker by passing in the
// messagingSenderId.
firebase.initializeApp({
'messagingSenderId': 'XXXX'
});
const messaging = firebase.messaging();
messaging.setBackgroundMessageHandler(payload => {
console.log('[firebase-messaging-sw.js] Received background message ', payload);
let notificationData = JSON.parse(payload.data.notification);
const notificationOptions = {
body: notificationData.body,
data: {
clickUrl: notificationData.clickUrl
}
};
return self.registration.showNotification(notificationData.title,
notificationOptions);
});
self.addEventListener('notificationclick', event => {
console.log('[firebase-messaging-sw.js] Notification OnClick: ', event);
// Android doesn’t close the notification when you click on it
// See: http://crbug.com/463146
event.notification.close();
// This looks to see if the current is already open and
// focuses if it is
event.notification.close();
let validUrls = /localhost:4200/;
let newUrl = event.notification.data.clickUrl || '';
function endsWith(str, suffix) {
return str.indexOf(suffix, str.length - suffix.length) !== -1;
}
event.waitUntil(
clients.matchAll({
includeUncontrolled: true,
type: 'window'
})
.then(windowClients => {
for (let i = 0; i < windowClients.length; i++) {
let client = windowClients[i];
if (validUrls.test(client.url) && 'focus' in client) {
if (endsWith(client.url, newUrl)) {
console.log('URL already open, focusing.');
return client.focus();
} else {
console.log('Navigate to URL and focus', client.url, newUrl);
return client.navigate(newUrl).then(client => client.focus());
}
}
}
if (clients.openWindow) {
console.log('Opening new window', newUrl);
return clients.openWindow(newUrl);
}
})
);
});
The vast majority of my SW code is taken from:
https://gist.github.com/vibgy/0c5f51a8c5756a5c408da214da5aa7b0
I'd recommend leaving out includeUncontrolled: true from your clients.matchAll().
The WindowClient that you're acting on might not have the current service worker as its active service worker. As per item 4 in the specification for WindowClient.navigate():
If the context object’s associated service worker client’s active
service worker is not the context object’s relevant global object’s
service worker, return a promise rejected with a TypeError.
If you can reproduce the issue when you're sure the client is currently controlled by the service worker, then there might be something else going on, but that's what I'd try as a first step.
This worked for me:
1- create an observable and make sure not to call the messaging API before it resolves.
2- register the service worker yourself, and check first if its already registered
3- call event.waitUntil(clients.claim()); in your service worker
private isMessagingInitialized$: Subject<void>;
constructor(private firebaseApp: firebase.app.App) {
navigator.serviceWorker.getRegistration('/').then(registration => {
if (registration) {
// optionally update your service worker to the latest firebase-messaging-sw.js
registration.update().then(() => {
firebase.messaging(this.firebaseApp).useServiceWorker(registration);
this.isMessagingInitialized$.next();
});
}
else {
navigator.serviceWorker.register('firebase-messaging-sw.js', { scope:'/'}).then(
registration => {
firebase.messaging(this.firebaseApp).useServiceWorker(registration);
this.isMessagingInitialized$.next();
}
);
}
});
this.isMessagingInitialized$.subscribe(
() => {
firebase.messaging(this.firebaseApp).usePublicVapidKey('Your public api key');
firebase.messaging(this.firebaseApp).onTokenRefresh(() => {
this.getToken().subscribe((token: string) => {
})
});
firebase.messaging(this.firebaseApp).onMessage((payload: any) => {
});
}
);
}
firebase-messaging-sw.js
self.addEventListener('notificationclick', function (event) {
event.notification.close();
switch (event.action) {
case 'close': {
break;
}
default: {
event.waitUntil(clients.claim());// this
event.waitUntil(clients.matchAll({
includeUncontrolled: true,
type: "window"
}).then(function (clientList) {
...
clientList[i].navigate('you url');
...
}
}
}
}
I am using Ionic 2, and am trying to get Push Notifications working.
I have registered my app with Firebase, and can push notifications to it successfully.
I now need to set up, so that I can push notifications from my app. So I decided to use the following Cordova Plugin (cordova-plugin-fcm).
Question 1
When I follow it's instructions, by doing the following in my Ionic app:
app.ts
declare var FCMPlugin;
...
initializeApp() {
this.platform.ready().then(() => {
...
FCMPlugin.getToken(
function (token) {
....
I get the following Error at runtime:
EXCEPTION: Error: Uncaught (in promise): ReferenceError: FCMPlugin is
not defined
How do I solve this please?
Question 2
In order to send notifications from your app, the Cordova Plugin (cordova-plugin-fcm) instructs the following:
//POST: https://fcm.googleapis.com/fcm/send
//HEADER: Content-Type: application/json
//HEADER: Authorization: key=AIzaSy*******************
{
"notification":{
"title":"Notification title", //Any value
"body":"Notification body", //Any value
"sound":"default", //If you want notification sound
"click_action":"FCM_PLUGIN_ACTIVITY", //Must be present for Android
"icon":"fcm_push_icon" //White icon Android resource
},
"data":{
"param1":"value1", //Any data to be retrieved in the notification callback
"param2":"value2"
},
"to":"/topics/topicExample", //Topic or single device
"priority":"high", //If not set, notification won't be delivered on completely closed iOS app
"restricted_package_name":"" //Optional. Set for application filtering
}
This is not even Typescript or Javascript. So where does it go? I just don't understand. Any advise appreciated.
You should have FCMPlugin.js included in your HTML index file
find the path for js file into plugins directory of the app
Example : MyFCM\plugins\cordova-plugin-fcm\www\FCMPlugin.js
app.controller('AppCtrl', function(FCMPlugin,$scope,$cordovaToast,$cordovaDialogs,ionPlatform) {
// call to register automatically upon device ready
ionPlatform.ready.then(function (device) {
console.log('I am working');
FCMPlugin.onNotification(
function(data){
if(data.wasTapped){
//Notification was received on device tray and tapped by the user.
$cordovaDialogs.alert(data.notification.body);
}else{
//Notification was received in foreground. Maybe the user needs to be notified.
$cordovaDialogs.alert(data.notification.body);
//$cordovaToast.showShortCenter( JSON.stringify(data) );
}
},
function(msg){
$cordovaToast.showShortCenter('onNotification callback successfully registered: ' + msg);
},
function(err){
$cordovaToast.showShortCenter('Error registering onNotification callback: ' + err);
}
);
});
})