So I have this code on my web app:
const connectedRef = firebase.database().ref('.info/connected')
connectedRef.on('value', function(snap) {
if (snap.val() === true) {
console.log('CONNECT')
connected = true
} else {
console.log('DISCONNECT')
connected = false
}
})
When I go offline using the "offline" checkbox in the Developer tools, I expect to see a single DISCONNECT message. What I see instead is:
-- app starts
DISCONNECT
CONNECT
-- here I go "Offline"
DISCONNECT
CONNECT -- What ?
I don't undestand why I see my application getting immediately "connected" again while I'm still offline. Bug? Or I'm doing something wrong?
Related
I am trying to figure out how to correctly work with WebApp added to Telegram API.
So, I have a simple setup of a React app and Bot. React app has counter and all I need is send counter data back to bot using sendData method.
Bot returns keyboard button, as mentioned in telegram docs with link to my web-app
private async returnButton(ctx: Context<Update>): Promise<void | object> {
ctx.reply('Enter number', Markup.keyboard([
Markup.button.webApp('Open counter', 'https://75bc-185-115-37-241.eu.ngrok.io')
]).resize())
return {};
}
Here's part of React app:
useEffect(() => {
Telegram.WebApp.ready();
Telegram.WebApp.MainButton.isVisible = true;
setDebug(Telegram.WebApp.sendData.toString());
}, [])
useEffect(() => {
Telegram.WebApp.onEvent('mainButtonClicked', () => {
Telegram.WebApp.MainButton.text = 'Clicked!';
try {
Telegram.WebApp.sendData(JSON.stringify({ counter }));
setDebug(`Sent`);
} catch (e) {
setDebug(`${e}, ${JSON.stringify(e)}`)
}
})
}, [counter])
I've added setDebug(Telegram.WebApp.sendData.toString()) just to
make sure method is present. I didn't find any good ways for debugging, as I have no
access to smth like devtools in webapp window
So below gif shows what happens when I click button on Mac client. Debug data set to Sent and no errors pops out. But modal doesn't close as it should and most importantly bot doesn't receive any data from webapp.
Though using iOS/ipadOS telegram flow works fine. Window closes and data sent to bot.
I have tried to reinstall Telegram client, but still no changes. Did I miss something or this is Mac client bug?
to get data from the main button you need to open the app with your keyboard. This will not work with an inline keyboard.
The only solution I found online was for Android- not for Unity- by listening to ('.info/connected')
like here- Detect if Firebase connection is lost/regained.
But I tried it and it doesn't work (tried to translate their Android solution to C#)-
DatabaseReference connectedRef = FirebaseDatabase.DefaultInstance.GetReference(".info/connected");
connectedRef.ValueChanged += (object sender, ValueChangedEventArgs a) => {
bool isConnected = (bool)a.Snapshot.Value;
print("isConnected" + isConnected);
};
When I try my code:
Test #1:
Connected to the internet- starting the app
log- isConnected = true
disconnect from the internet
a lot of socket errors, no calls to isConnected anymore (still true)
Test #2:
Disconnected to the internet- starting the app
log- isConnected = false
a lot of socket errors
Connect to the internet
log- isConnected = true
Which means= listeners don't work on offline mode
and the reason why I get isConnected = false only on test #2 is because the function is being called once on start...
How can I tell when the user isn't connected? It's important because I have to manage everything manually until the user is online again- to update the database.
How one forces Windows to disconnect from BLE device being used in UWP app? I receive notifications from some characteristics but at some point I want to stop receiving them and make sure I disconnect from the BLE device to save BLE device's battery?
Assuming your application is running as a gatt client and you have the following instances your are working with in your code:
GattCharacteristic myGattchar; // The gatt characteristic you are reading or writing on your BLE peripheral
GattDeviceService myGattServ; // The BLE peripheral' gatt service on which you are connecting from your application
BluetoothLEDevice myBleDev; // The BLE peripheral device your are connecting to from your application
When you are already connected to your BLE peripheral, if you call the Dispose() methods like this :
myBleDev.Dispose(); and/or myGattServ.Dispose(); and/or myGattchar.Service.Dispose()
you surely will free resources in your app but will not cleanly close the BLE connection: The application looses access to control resources for the connection. Nevertheless, connection remains established on the lower levels of the stack (On my peripheral device the Bluetooth connection active LED remains ON after calling any of Dispose() methods).
Forcing disconnection is done by first disabling notifications and indications on the concerned characteristic (i.e. myGattchar in my example above) by writing a 0 (zero) to the Client Characteristic Configuration descriptor for that characteristic through call to method WriteClientCharacteristicConfigurationDescriptorAsync with parameter GattClientCharacteristicConfigurationDescriptorValue.None :
GattCommunicationStatus status =
await myGattchar.WriteClientCharacteristicConfigurationDescriptorAsync(
GattClientCharacteristicConfigurationDescriptorValue.None);
Just dispose all objects related to the device. That will disconnect the device, unless there are other apps connected to it.
For my UWP app, even though I've used Dispose() methods, I still received notifications. What helped me was setting my device and characteristics to null. Example:
device.Dispose();
device = null;
Not all to certain of how "correct" this programming is, but it's been working fine for me so far.
The UWP Bluetooth BLE sample code from Microsoft (dispose the BLE device) didn't work for me. I had to add code (dispose the service) to disconnect the device.
private async Task<bool> ClearBluetoothLEDeviceAsync()
{
if (subscribedForNotifications)
{
// Need to clear the CCCD from the remote device so we stop receiving notifications
var result = await registeredCharacteristic.WriteClientCharacteristicConfigurationDescriptorAsync(GattClientCharacteristicConfigurationDescriptorValue.None);
if (result != GattCommunicationStatus.Success)
{
return false;
}
else
{
selectedCharacteristic.ValueChanged -= Characteristic_ValueChanged;
subscribedForNotifications = false;
}
}
selectedService?.Dispose(); //added code
selectedService = null; //added code
bluetoothLeDevice?.Dispose();
bluetoothLeDevice = null;
return true;
}
Remember you must call -= for events you have called += or Dispose() will never really garbage collect correctly. It's a little more code, I know. But it's the way it is.
Not just with bluetooth stuff, I will remind you - with everything. You can't have hard referenced event handlers and get garbage collection to work as expected.
Doing all the disposing and null references suggested didn't achieve the Windows (Windows Settings) disconnection I was looking for.
But dealing with IOCTL through DeviceIoControl did the job.
I found that after calling GattDeviceService.GetCharacteristicsAsync(), BluetoothLeDevice.Dispose() does not work. So I dispose the Service I don't need.
GattCharacteristicsResult characteristicsResult = await service.GetCharacteristicsAsync();
if (characteristicsResult.Status == GattCommunicationStatus.Success)
{
foreach (GattCharacteristic characteristic in characteristicsResult.Characteristics)
{
if (characteristic.Uuid.Equals(writeGuid))
{
write = characteristic;
}
if (characteristic.Uuid.Equals(notifyGuid))
{
notify = characteristic;
}
}
if (write == null && notify == null)
{
service.Dispose();
Log($"Dispose service: {service.Uuid}");
}
else
{
break;
}
}
Finally, when I want to disconnect the Bluetooth connection
write.Service.Dispose();
device.Dispose();
device = null;
I'm using Distriqt Push Notifications Extension and I can't get it working correctly if the user does not allow PNs on first run: the application ends registering the user because it states that PNs are enabled and available.
I do the following:
if (PushNotifications.isSupported()) {
registerPushNotifications();
}
private function registerPushNotifications():void {
PushNotifications.service.addEventListener(PushNotificationEvent.REGISTER_SUCCESS, onPushNotificationToken);
PushNotifications.service.register(MODEL.Configuration.GCM_SENDER_ID);
}
private function onPushNotificationToken(event:PushNotificationEvent):void {
if (PushNotifications.service.isEnabled) { registerDevice(); }
}
Does not PushNotifications.service.isEnabled supposed to be false if the user disallows it? When does it become false? How am I supposed to handle this case scenario?
I've found what was happening in my application:
I'm handling activate/deactivate events to enable and disable background execution: NativeApplication.nativeApplication.executeInBackground = true;. This makes your application able to run on background, ignoring the UI which asks for user permission and it happens that PushNotifications.service.isEnabled is true on first run after installation.
What I've done is delaying adding activation and deactivation listeners till one of this things happen first:
The device does not support push notifications PushNotifications.isEnabled == false
When the device receive a push token
When the device fails receiving a push token
I hope this helps someone.
Just posting this here for anyone else who has issues with the isEnabled flag:
var hasRequestedPermissionsOnce:Boolean = false;
// You should load hasRequestedPermissionsOnce from some persistent storage, defaulting to false
...
PushNotifications.init( APP_KEY );
if (PushNotifications.isSupported)
{
if (PushNotifications.service.isEnabled)
{
// Notifications have been enabled by the user
// You are free to register and expect a registration success
register();
}
else if (!hasRequestedPermissionsOnce)
{
// You should implement hasRequestedPermissionsOnce somewhere to check if this is the first run of the app
// If we haven't called register once yet the isEnabled flag may be false as we haven't requested permissions
// You can just register here to request permissions or use a dialog to delay the request
register();
}
else
{
// The user has disabled notifications
// Advise your user of the lack of notifications as you see fit
}
}
...
private function register():void
{
// You should save hasRequestedPermissionsOnce to a shared object, file or other persistent storage
hasRequestedPermissionsOnce = true;
PushNotifications.service.addEventListener( PushNotificationEvent.REGISTER_SUCCESS, registerSuccessHandler );
PushNotifications.service.addEventListener( PushNotificationEvent.REGISTER_FAILED, registerFailedHandler );
PushNotifications.service.register( GCM_SENDER_ID );
}
Original source here: https://gist.github.com/marchbold/fb0438cf326a44cea0cf#file-distriqt-extensions-pushnotifications-isenabled-as
I'm currently building an android application using ionic/ngcordova. I'm at the point of implementing push notifications. I've implemented push notifications as a service which is injected at app.run(function(){..}) stage. The registration part works and I receive a callback containing the regid. Also, when the application is in the active state, the event is raised and the notification is received.
The problem I'm having is that when the application goes into the background, the notifications are not received at all. I would expect that a local notification would be raised when the app isn't running or something similar, but absolutely nothing happens, which is weird.
I've trawled the web for the last couple of days looking for a solution but I've been unable to find anything which kind of indicates to me that it should just work.
The following is my notificationService.js inside my app
app.factory('notificationService', ['$cordovaPush', function($cordovaPush){
var dataFactory = {};
//
// When the device is ready and this service has been plumbed in...
document.addEventListener("deviceready", function(){
console.log("initializing push notifications...");
_register();
}, false);
//
// Registers the device for push notifications...
var _register = function(){
var config = {};
if ( device.platform == 'android' || device.platform == 'Android' || device.platform == "amazon-fireos" ){
// TODO: centralise this value as it can change...
config = {
senderID: "448168747432",
ecb: "onNotificationGCM"
};
}else {
// iOS
config = {
"badge":"true",
"sound":"true",
"alert":"true"
};
// Can add the following property to the config object to raise a callback with the information if need be...
// "ecb": "onNotificationRegisterAPN"
}
$cordovaPush.register(config).then(function(result){
//
// Typically returns "ok" for android and devicetoken for iOS
console.log(result);
});
};
window.onNotificationGCM = function(result){
console.log(result);
/*
I get called when the app is in the foreground, but nothing happens when the app is in the background.
*/
};
dataFactory.register = _register;
return dataFactory;
}]);
If it helps, I'm using PushSharp via a .net application in order to deliver the notifications. Any help would be greatly appreciated.
UPDATE: I'm using the following frameworks/libs:
Ionic Framework 1.2.14-beta6
Cordova 4.2.0
PushPlugin
For anyone else who's been pulling their hair out for a couple of days like I have, the solution was really simple...I was missing two properties in my Pushsharp QueueNotification request. So using the example given on the PushSharp github repo here: https://github.com/Redth/PushSharp#sample-code
push.QueueNotification(new GcmNotification().ForDeviceRegistrationId("DEVICE-REGISTRATION-ID-HERE").WithJson("{\"alert\":\"Hello World!\",\"badge\":7,\"sound\":\"sound.caf\"}"));
Needs to be updated to add the missing properties:
push.QueueNotification(new GcmNotification().ForDeviceRegistrationId("DEVICE REGISTRATION ID HERE")
.WithJson(#"{""alert"":""This is the future"",""badge"":7,""sound"":""sound.caf"",""title"":""Status Bar title"",""message"":""Some text you want to display to the user""}"));
Otherwise if your app happens to be developed using Cordova and its not currently in the foreground, nothing, repeat nothing will happen.
Tip my hat to gdelavald with his comment on PushPlugin for pointing me in the right direction here:
https://github.com/phonegap-build/PushPlugin/issues/212