Web bluetooth DOMException: GATT Error: Not supported - javascript

I am trying to receive data from my ESP32 via the Web Bluetooth API.
The device can connect to the webpage but after starting to listen to notifications I get the following error:
DOMException: GATT Error: Not supported
There is another thread that has a similar question but there is a properties problem.
My properties seem to be okay
This is my code:
let filters = [];
filters.push({name: 'Custom device name'});
let options = {};
options.filters = filters;
try {
const device = await navigator.bluetooth.requestDevice(options);
const connectedDevice = await device.gatt.connect();
console.log('Connected');
const batteryService = await connectedDevice.getPrimaryService('__SERVICE_GUID__');
const batteryLevelCharacteristic = await batteryService.getCharacteristic('__CHARACTERISTIC_GUID__');
var properties = batteryLevelCharacteristic.properties;
console.log(properties);
if (batteryLevelCharacteristic.properties.notify) {
batteryLevelCharacteristic.addEventListener(
"characteristicvaluechanged",
async (event) => {
debugger;
//console.log(`Received value: ${event.target.value}`);
}
);
await batteryLevelCharacteristic.startNotifications();
}
}
catch(error) {
console.log(error);
}
First I get the message Connected
Then i get the properties:
authenticatedSignedWrites : false
broadcast : false
indicate : true
notify : true
read : true
reliableWrite : false
writableAuxiliaries : false
write : true
writeWithoutResponse : false
So Notify is set to true.
At the end I go into the Catch with the error:
DOMException: GATT Error: Not supported.
Please let me know if I missed important information

Add needed services to filters or optionalServices if a device does not advertise that service to enable access.
let options = {
filters: [
{ services: ['__SERVICE_GUID__'] },
{ name: 'Custom device name' }
],
optionalServices: ['__SERVICE_GUID__'],
};

Related

I am facing an undefined reading length error in my code below

This is the error I am getting when I try to deploy the code:
Error: ERROR processing /home/anooj-patnaik/hh-fcc/hardhat-fund-me-fcc/deploy/00-deploy-mocks.js:
TypeError: Cannot read properties of undefined (reading 'length')
const { network } = require("hardhat")
const {
developmentChains,
DECIMALS,
INITIAL_ANSWER,
} = require("../helper-hardhat-config")
module.exports = async ({ getNamedAccounts, deployments }) => {
const { deploy, log } = deployments
const { deployer } = await getNamedAccounts()
if (developmentChains.includes(network.name)) {
log("Local Network Detected! Deploying Mocks...")
await deploy("MockV3Aggregator", {
contract: "MockV3Aggregator",
from: deployer,
log: true,
args: [DECIMALS, INITIAL_ANSWER],
})
log("Mocks deployed")
log("---------------------------")
}
}
module.exports.tags = ["all", "mocks"]
I have defined all the variables in a hardhat-helper-config.js and hardhat.config.js. The MockV3Aggregator is in a separate contract
Tried to deploy the code above and faced with an error
When you call await getNamedAccounts(), it looks in your hardhat.config.js for the namedAccounts section, and reads the length of the named accounts.
You'll want to make sure this is in there!
namedAccounts: {
deployer: {
default: 0, // here this will by default take the first account as deployer
},
},

Advice converting an onCreate firebase cloud function trigger with FCM Messaging to support async/await and database reads

I initially had a simple firebase cloud function that sent out a push notification to a topic when a new message child was created in my real-time database. But I wanted to add message filtering where notifications for messages from some filtered users would be sent only to admin users. For this, I have created user groups in my real-time database of the format {userName: FIRToken}, which gets written to from my iOS App every time it launches and I get a FIRToken. So now I will have to load 2 lists 1) Admin Users, 2) Filtered Users before I can actually decide where to send the notification.
So I looked into ways to do this and async/await seemed better than doing a promise inside a promise for loading my 2 user lists. I then saw a firestore video tutorial where a similar usecase function was converted to use async/await instead of promises in promises. Following that, I refactored my code to await on the 2 snapshots for admin and filtered users, before going on to decide where to send the notification and return a promise. My refactoring seems correct. But unfortunately, my old iPhone is stuck on <DeviceName> is busy: Copying cache files from device. Hence I can't physically login from 2 different devices and test if the notifications are going only to my admin user account. Which is why I am posting my function here to see if I have refactored my code correctly or missed something. Please let me know if I will get the intended results or I should fix something in the code.
Edit: Updated code to fix these issues:
Also, the methods to send messages are very confusing. send needs topic name to be defined in the payload but does not support apns. sendToTopic needs a topic name as an argument with the payload. sendMulticast fails to send messages to users whereas sendToDevice sends properly.
Finally sendToDevice supports sound field in notification field, but send does not.
functions.database
.ref("/discussionMessages/{autoId}/")
.onCreate(async (snapshot, context) => {
// console.log("Snapshot: ", snapshot);
try {
const groupsRef = admin.database().ref("people/groups");
const adminUsersRef = groupsRef.child("admin");
const filteredUsersRef = groupsRef.child("filtered");
const filteredUsersSnapshot = await filteredUsersRef.once("value");
const adminUsersSnapshot = await adminUsersRef.once("value");
var adminUsersFIRTokens = {};
var filteredUsersFIRTokens = {};
if (filteredUsersSnapshot.exists()) {
filteredUsersFIRTokens = filteredUsersSnapshot.val();
}
if (adminUsersSnapshot.exists()) {
adminUsersFIRTokens = adminUsersSnapshot.val();
}
// console.log(
// "Admin and Filtered Users: ",
// adminUsersFIRTokens,
// " ",
// filteredUsersFIRTokens
// );
const topicName = "SpeechDrillDiscussions";
const message = snapshot.val();
// console.log("Received new message: ", message);
const senderName = message.userName;
const senderCountry = message.userCountryEmoji;
const title = senderName + " " + senderCountry;
const messageText = message.message;
const messageTimestamp = message.messageTimestamp.toString();
const messageID = message.hasOwnProperty("messageID")
? message.messageID
: undefined;
const senderEmailId = message.userEmailAddress;
const senderUserName = getUserNameFromEmail(senderEmailId);
const isSenderFiltered = filteredUsersFIRTokens.hasOwnProperty(
senderUserName
);
console.log(
"Will attempt to send notification for message with message id: ",
messageID
);
var payload = {
notification: {
title: title,
body: messageText,
},
data: {
messageID: messageID,
messageTimestamp: messageTimestamp,
},
apns: {
payload: {
aps: {
sound: "default",
},
},
},
};
console.log("Is sender filtered? ", isSenderFiltered);
if (isSenderFiltered) {
adminFIRTokens = Object.values(adminUsersFIRTokens);
console.log("Sending filtered notification with sendMulticast()");
payload.tokens = adminFIRTokens; //Needed for sendMulticast
return admin
.messaging()
.sendMulticast(payload)
.then((response) => {
console.log(
"Sent filtered message (using sendMulticast) notification: ",
JSON.stringify(response)
);
if (response.failureCount > 0) {
const failedTokens = [];
response.responses.forEach((resp, idx) => {
if (!resp.success) {
failedTokens.push(adminFIRTokens[idx]);
}
});
console.log(
"List of tokens that caused failures: " + failedTokens
);
}
return true;
});
} else {
console.log("Sending topic message with send()");
payload.topic = topicName;
return admin
.messaging()
.send(payload)
.then((response) => {
console.log(
"Sent topic message (using send) notification: ",
JSON.stringify(response)
);
return true;
});
}
} catch (error) {
console.log("Notification sent failed:", error);
return false;
}
});

How to send notification using FCM?

I wrote a cloud function, to listen for document creation in a collection, in my database
here is the function,
const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp(functions.config().functions);
var newData;
exports.myTrigger = functions.firestore.document('FCM/{id}').onCreate(async (snapshot, context) => {
//
if (snapshot.empty) {
console.log('No Devices');
return;
}
newData = 'hello';
const deviceIdTokens = await admin
.firestore()
.collection('FCM')
.get();
var tokens = [];
var i=0;
for (var token of deviceIdTokens.docs) {
tokens.push(token.data().ar1[i]);
i++;
}
var payload = {
notification: {
title: 'push title',
body: 'push body',
sound: 'default',
},
data: {
push_key: 'Push Key Value',
key1: newData,
},
};
try {
const response = await admin.messaging().sendToDevice(tokens, payload);
console.log('Notification sent successfully');
} catch (err) {
console.log(err);
}
});
This function works weirdly,
For example, sometimes it sends notification, and sometimes it does not.
It throws errors like " TypeError: Cannot read property '0' of undefined".
I don't know how to resolve this issue,
In my arr1 field, i have an array of device tokens, to whom i want to send notifications to,
i want the function to send notifications only to the devices(using tokens) which are just created(in the newly created document ),then delete the document.
I think it's sending notifications to all the documents at once.
I'm pretty new at node..
please help me out.
UPDATE:-
Here is my document structure
Type error coming from this line:
tokens.push(token.data().arr1[i]);
So all I can say is that sometimes token.data() doesn't have an arr1 attribute.

Actions Sdk get this error TypeError: Cannot read property 'output' of undefined

I'm trying to connect IBM Watson and Google Assistant, but I keep receiving this error "TypeError: Cannot read property 'output' of undefined" and this "Function execution took 3323 ms, finished with status: 'crash'"
This is my code:
const {actionssdk} = require('actions-on-google');
const functions = require('firebase-functions');
const app = actionssdk({debug: true});
app.intent('actions.intent.MAIN', (conv) => {
conv.ask('Olá, como posso lhe ajudar?');
});
app.intent('actions.intent.TEXT', (conv, input) => {
var AssistantV1 = require('watson-developer-cloud/assistant/v1');
var assistant = new AssistantV1({
username: '###################################',
password: '###################################',
url: '###################################',
version: '2018-07-10'
});
conv.ask("eeeeeeeeeeeeeeeee");
return new Promise( (resolve, reject) => {
assistant.message(
{
workspace_id: '###################################',
input: { text: input },
headers: {'Content-Type':'application/json'}
},
function(err, response) {
conv.ask(response.output.text[0]);
resolve();
}
);
})
});
exports.dialogflowFirebaseFulfillment = functions.https.onRequest(app);
Rebeca, just to adding information, you are trying to add some outbound access, but you need to configure your account to do that.
"Billing account not configured. External network is not accessible
and quotas are severely limited. Configure billing account to remove
these restrictions"
If you wanted to call some API (IBM Watson, as verified) you'd need to enable billing.
For the other quotas, take a look here to see prices - as you can see there are limits to the number of invocations using free tier.
Your responseobject is null. Check it is not equal to null before to use it:
let speech;
if (response !== null) {
speech = response.output.text[0];
}
else{
speech = "I'm sorry, there was an error and I'm unable to answer";
}
conv.ask(speech);

Push notifications in Progressive web app through GCM

while sending push notification i got ( Uncaught (in promise) ReferenceError: require is not defined(…)) error.here is my code
const endPoint = subscription.endpoint.slice(subscription.endpoint.lastIndexOf('/')+1);
console.log(endPoint);
var gcm = require('node-gcm');
var message = new gcm.Message({
notification: {
title: "Hello, World",
icon: "ic_launcher",
body: "This is a notification that will be displayed ASAP.",
tag:"hello"
}
});
var regTokens = [endPoint];
var sender = new gcm.Sender('AIzaSyD9Bcxd_MQZFoGjO1y_hPm-xUdgnM25Ny4'); //API Key
// Now the sender can be used to send messages
sender.send(message, { registrationTokens: regTokens }, function (error, response) {
if (error) {
console.error(error);
res.status(400);
}
else {
console.log(response);
res.status(200);
}
});
})
})
}
Screenshot of error
enter image description here
This code uses require, so it looks to me like you're trying to use node code in the browser. To do that you'll need to use something like Browserify, although I'm not sure that's going to work for node-gcm as it may have certain requirements about sending network requests without cross origin restrictions etc.

Categories