How to close Camera using phonegap-barcode-scanner plugin within service IONIC - ionic-framework

I am using phonegap-barcodescanner-plugin to read qr while a service is reading instant payments on background.
I am detecting a new instant payment in the service and launching an event subscribed in the page where the barcodeScanner is launched
event.subscribe('instant-payment', (val) => {
console.log("Hi--------------", val)
this.navCtrl.pop()
});
the event is correctly fired and the log is ok but I'm trying to do a navCtrl.pop() and the Activity is never closed, I thought was going to work same way like cancelling scanner
scan() {
this.barcodeScanner.scan(this.options).then(barcodeData => {
if (barcodeData.cancelled == true) {
this.navCtrl.pop()
} else {
}
}).catch(err => {
console.log('Error', err);
});
}
Is there anyway to force close barcodeScanner and go back to the last "IonicPage".
Thanks for any help.

Related

PWA Web Bluetooth API from page to another

I'm building a PWA using Web Bluetooth API. Connection is OK, I set an eventlistener for getting data and when my Arduino with BLE module HM10 send data, I get them.
But my PWA has more than one page. So on first one I have a "Connection" button, and after connection I "listen".
When I go to a second page, I use navigator.bluetooth.getDevices() to get previsouly connected device.
But I get an empty list.
I though my getDevices() function was bugged but I discoverd a strange thing:
my PWA run a browser tab on Chrome. I connect to the device. Then, on another tab I open this url with a Google example (https://googlechrome.github.io/samples/web-bluetooth/get-devices.html) and call Get Bluetooth Devices to get list of connected device, I see my device in this example page.
Without closing this second tab, I use my PWA: all page are able to get the device (using navigator.bluetooth.getDevices()), set the even and get data from the Arduino. Great!
If I close this tab, connection is lost...
So I think my "connection" is not perfect and when I close my PWA first page, I loose it... But as example avaible on internet are about "one page", I'm a bit lost (like the device connection in fact...).
Here is the code I use:
function reconnect_ble()
{
console.log('Search previously connected devices...');
navigator.bluetooth.getDevices()
.then(devices => {
console.log('> Got ' + devices.length + ' Bluetooth devices.');
if (devices.length == 0)
{
alert("No module");
return false;
}
var flag_module = false;
for (const device of devices)
{
var nom = device.name;
// Check if it's our modle
if (nom == pwa_hm10)
{
flag_module = connectToBluetoothDevice(device);
}
}
if (flag_module == false)
{
alert("Nothing for us");
return false;
}
else
{
return true;
}
})
.catch(error => {
console.log('Erreur:' + error);
});
}
//===================================================================================
// First Connection
function connect_ble()
{
return (deviceCache ? Promise.resolve(deviceCache) :
requestBluetoothDevice()).
then(device => connectToBluetoothDevice(device)).
catch(error => display_info(error));
}
//-------------------------------------------------------------------------------------
function connectToBluetoothDevice(device)
{
const abortController = new AbortController();
// Evenement sur ce device
device.addEventListener('advertisementreceived', (event) =>
{
console.log('connectToBluetoothDevice- Advertisements from "' + device.name + '"...');
// Stop watching advertisements to conserve battery life.
abortController.abort();
// Connexion au serveur GATT
device.gatt.connect()
.then(() =>
{
console.log('connectToBluetoothDevice - Server GATT from "' + device.name + '"...');
// Set our event
connectDeviceAndCacheCharacteristic(device).
then(characteristic => startNotifications(characteristic)).
catch(error => display_info(error));
})
.catch(error =>
{
// Erreur pas de connexion
console.log(error);
});
}, { once: true });
console.log('connectToBluetoothDevice - Watching advertisements from "' + device.name + '"...');
device.watchAdvertisements({ signal: abortController.signal })
.catch(error =>
{
console.log(error);
});
}
//----------------------------------------------------------------------------------
// Form to choose device
function requestBluetoothDevice()
{
return navigator.bluetooth.requestDevice(
{
acceptAllDevices: true,
optionalServices: [0xFFE0]
}).
then(device => {
display_info('Selected: ' + device.name);
deviceCache = device;
deviceCache.addEventListener('gattserverdisconnected',handleDisconnection);
return deviceCache;
});
}
//-----------------------------------------------------------------------------------
function connectDeviceAndCacheCharacteristic(device)
{
if (device.gatt.connected && characteristicCache)
{
return Promise.resolve(characteristicCache);
}
return device.gatt.connect().
then(server => {
return server.getPrimaryService(0xFFE0);
}).
then(service => {
return service.getCharacteristic(0xFFE1);
}).
then(characteristic => {
display_info('characteristic founded');
characteristicCache = characteristic;
return characteristicCache;
});
}
//------------------------------------------------------------------------------------
function startNotifications(characteristic)
{
return characteristic.startNotifications().
then(() => {
characteristic.addEventListener('characteristicvaluechanged',handleCharacteristicValueChanged);
});
}
//--------------------------------------------------------------------------------------
function handleCharacteristicValueChanged(event)
{
// Decoding received data
var decodage = new TextDecoder().decode(event.target.value);
traitement_data_ble(decodage);
}
Edit
If you connect to the bluetooth on Page 1, and go to Page 2 on same tab, connection is lost.
If you connect to the bluetooth on Page 1, set an event listenner to get data then open Page 2 on another tab, Page 2 will "see" the bluetooth module, but even if Page 2 set an event listener, this is even from Page 1 that will receive the data.
If you connect to the bluetooth on Page 1, don't set event listenner, open Page 2 in other tab and set event listenner on Page 2, Page 2 will receive the data.
So case 3 seems to be the only way. Maybe using iFrame for the connection page??
Accessing the same device from multiple pages is not supported and the fact that it seems to partially work is more of a bug than a feature. A device can't effectively distinguish between multiple pages on the same host trying to communicate with it so you need to have a single piece of code which manages the connection to the device.
The correct way to do this today is to create a single-page application so that the connection held by that page can remain own even if the user navigates to different "pages" of your application. If you need to create separate windows these can communicate with the device by sending commands back through the single page that owns the connection using postMessage or Broadcast Channel.
The ideal solution, which is not currently supported, is to use a Shared Worker for this. Shared Workers are a type of web worker which is owned by all the currently open pages of your app at once. It can thus hold shared state (such as the Bluetooth connection) in behalf of your application and won't exit unless every window of your app is closed.

Which is better approach to send push notification in Kuzzle using hooks or subscription?

I’m using Kuzzle as backend for my realtime chat application.
What is the better approach to sending push notification when user is offline in a mobile chat app?
1. Using custom plugin hooks
// check for every message in chat
this.hooks = {
'document:afterCreate': (request) => {
if (request.input.resource.collection == 'messages') {
let message = request.input.body;
this.context.accessors.sdk.document.get('now', 'user_sessions', message.otherUserId).then((userSession) => {
if (!userSession._source.isOnline) {
userSession._source.devices.forEach(device => {
// send push notification
});
}
})
}
}
}
2. Subscription per user for all users after the Kuzzle server start-up
const app = new Backend('kuzzlebackend')
app.start()
.then(async () => {
// Application started
// Loops through all users and adds their subscriptions to Kuzzle
foreach(user in users) {
app.sdk.realtime.subscribe('now', 'messages', { ‘otherUserId' : user._id }, async (notification: Notification) => {
this.context.accessors.sdk.document.get('now', 'user_sessions', user._id).then((userSession) => {
if (!userSession._source.isOnline) {
userSession._source.devices.forEach(device => {
// send push notification
});
}
})
})
}
})
You should use the hook mechanism on the generic:document:afterWrite event to send notification to offline users when a new message is created.
This event will be triggered every time a document is written with one of the Document controller action, and for the m* action family it you will able to process documents in bulk instead of one by one.

How can I keep the BarcodeScanner screen open without redirecting me to another page?

I am making an application that allows me to scan QR codes, and I managed to make the code work but my doubt is that when I scan the plugin phonegap-plugin-barcodescanner takes me out of the camera interface, what I want to do is to stay in it and show me an alert with the scanned code, and to give it ok in the alert to stay in it, to avoid being clicked to enter it.
I'm working with the plugin phonegap-plugin-barcodescanner, in ionic 3
public scanQR2() {
this._ButtonText = "Escanear";
this._barcodeScanner.scan().then((barcodeData) => {
if (barcodeData.cancelled) {
console.log("User cancelled the action!");
this._ButtonText = "Escanear";
return false;
}
console.log("Scanned successfully!");
console.log(barcodeData);
}, (err) => {
console.log(err);
});
}
I hope that the application when performing a scan stays on the same interface and does not redirect me to another page

Ionic Native - InAppPurchase2 - When calling store.when().approved() it runs the callback before the confirmation is complete

I'm setting up in app purchases in my Ionic app and I've been having some trouble getting the test purchases working correctly. It would seem that as soon as I execute this particular function, it automatically runs the code as if it was approved, even though the confirmation to get the subscription hasn't occurred yet:
this.platform.ready().then(() => {
// Register the products for consumption
this.products.forEach(product => {
this.store.register({
id: product.id,
alias: product.alias,
type: product.type
});
// When a purchase is approved, see what we get here
this.store.when(product.id).approved((order) => {
// Purchase was successful, setup the appropriate subscription
this._subscriptions.updateSubscription(this.user.id, this.selectedPlan.amount, 'activate').then(() => {
if(this.selectedPlan.amount === 1) {
this.subscriptionGrammar = 'month';
} else if(this.selectedPlan.amount > 1) {
this.subscriptionGrammar = 'months';
}
order.finish();
});
});
});
});
I was under the impression that utilizing the .when().approved() would only fire once the payment "goes through". Since I'm using test transactions, I'm not sure how that would affect it, but I would suspect it should only do that once I hit "Confirm" on the Google dialog that pops up in my app?
Is there something I'm missing here?

Ionic FCM push notifications observable does not emit

I am doing the following in an ionic application:
When a user is logged in, subscribe to their user ID topic
When a push notification arrives, console.log something.
this.authState.subscribe((state) => {
if (state) {
this.fcmPush.subscribeToTopic(state.uid);
this.fcmPush.onNotification().subscribe(notification => {
if (notification.wasTapped) {
console.log('Received in background', notification);
} else {
console.log('Received in foreground', notification);
}
});
}
});
Source: https://github.com/AmitMY/ionic-starter-firebase/blob/master/src/app/app.component.ts#L118
Sending a notification to my own topic arrives (after a few minutes), but I never see anything in console, both from outside the app, and inside the app.
What am I doing wrong?
Sending a notification from firebase messaging does not work.
However, using the sdk I must add:
click_action: "FCM_PLUGIN_ACTIVITY",
Which is in the usage guide but I missed