firebase - How to know which registration_id is bad/expired/deleted - firebase

So I am pushining notifications in a batch to multiple devices. I want to delete device GFCM tokens from my databse if they are not in firebase.
Test request:
{"registration_ids": ["fznIum-OIL0:APA91bE9n6gxqVEB3hR0On_TZqH_cOOO7rFyLE5MYbvKXUX3737IonXquZRoHeY1UJf20G4nrahz35p80X8PAPouviYvXgtekAzeDFuwaWyiPI1sFlN1d1wGp5OulXv9wUzHyegeZiih","dsasadadsasdasdasdasdefs","fjb0qTB9ACI:APA91bHvx0pSlq-NuQz-bU70DhL7BXAcd-DqT9YT0ZjYw7R_pkBmr8oe6XdNw8IPlU67d-rXMfRY3mybaO7K5GHo_NH7G-Ya1Ae2xxJP1JIbuuSYomz31y_MPQijFK8w-bZXQ26SWE09"],
"notification":{
"body":"Yoou have a new message from Alice"}}
And response:
{
"multicast_id": 7971310728176484096,
"success": 1,
"failure": 2,
"canonical_ids": 0,
"results": [
{
"error": "NotRegistered"
},
{
"error": "InvalidRegistration"
},
{
"message_id": "0:1481547993513035%4f9c20964f9c2096"
}
]
}
How to detect which registration_ids are bad/Not registered?
Thanks!

Okey, i think i figured it out.
"results": Returns responses/errors in the order you specified it in registration_ids

when you are sending push notification to any mobile,you can find in err that registartion_ids/token isbad /not registered/
var serverKey = 'sdasd';//server key
var fcm = new FCM(serverKey);
var token = "token";//token here
var message = {
to: token,
collapse_key: 'your_collapse_key',
notification: {title: 'hello', body: 'test'},
data: {my_key: 'my value', contents: "stackoverflow.com"}
};
fcm.send(message, function (err, response) {
if (err) {
console.log(err);//find here registration_ids are bad/Not registered?
} else {
console.log(response);
}
});
});

Related

Problem with Axios Get request - might be an Asynchronous problem

I seem to be having asynchronous problems. I'm using react, express, sequelize and mariadb for the entire app. I am using axios in my front end to make the get request. However, the get request always returns an empty value. However, in my backend code I know the request is calling the database findAll().
Front-end (React/Axios)
componentDidMount() {
this.getPets();
}
getPets = async () => {
try {
const resp = await axios.get('/getdogs');
this.setState({ pets: resp.body });
console.log(resp.data);
} catch (err) {
// Handle Error Here
console.error(err);
}
server.js
app.get('/getdogs', (req, res) => {
console.log("IN THE FUNCTION");
const pets = db.getPets();
console.log("All pets:", JSON.stringify(pets, null, 2));
res.send(pets);
});
database.js
async function getPets() {
const pets = await Pets.findAll();
console.log("All pets:", JSON.stringify(pets, null, 2));
return JSON.stringify(pets, null, 2);
}
output from server.js
nodemon] starting `node server.js`
Listening on port 5000
IN THE FUNCTION
All pets: {}
warning: please use IANA standard timezone format ('Etc/GMT0')
warning: please use IANA standard timezone format ('Etc/GMT0')
Executing (default): SELECT `id`, `name`, `createdAt`, `updatedAt` FROM `Pets` AS `Pets`;
All pets: [
{
"id": 1,
"name": "HULK",
"createdAt": "2020-09-15T23:09:43.000Z",
"updatedAt": "2020-09-15T23:09:43.000Z"
},
{
"id": 2,
"name": "Martha",
"createdAt": "2020-09-15T23:09:43.000Z",
"updatedAt": "2020-09-15T23:09:43.000Z"
},
{
"id": 3,
"name": "Bernie",
"createdAt": "2020-09-15T23:09:43.000Z",
"updatedAt": "2020-09-15T23:09:43.000Z"
}
]
An axios response does not have body property. Response is in the data property, see Response schema
this.setState({ pets: resp.data });
console.log(resp.data);
You haven't awaited a result from DB:
db.getPets().then(pets => {
console.log("All pets:", JSON.stringify(pets, null, 2));
res.send(pets);
});

API always error 408 - Invalid Data Type Sent

I really don't know what happen with this error (I mean by, is this related to the Flutter or Dart or the package that I used or the API that I used). In a nutshell, it always giving me back error code 408 - Invalid data type sent from my flutter App, while I COMPLETELY could done it in Postman and been tried it with PHP.
I just wanna call a normal POST request to my payment gateway API (I use Midtrans).
Here is my result:
From Postman
From my app in Flutter within VS Code
What am I doing wrong? I am completely has no clue about this.
I will give the detail below for anyone who want to try a simple call to this API so you can reproduce this.
Endpoint
https://api.sandbox.midtrans.com/v2/charge
Body
"payment_type": "bank_transfer",
"bank_transfer": {
"bank": "permata",
"va_number": "1234567890"
},
"transaction_details": {
"order_id": "order-101b-{{2020-11-0222rrd324dzz}}",
"gross_amount": 44000
},
"customer_details": {
"email": "richie.permana#gmail.com",
"first_name": "Richie",
"last_name": "Permana",
"phone": "+6281 1234 1234"
},
"item_details": [
{
"id": "item01",
"price": 21000,
"quantity": 1,
"name": "Schema Programmer"
},
{
"id": "item02",
"price": 23000,
"quantity": 1,
"name": "Ayam Xoxoxo"
}
]
}
This is the header
{
'content-type': 'application/json',
'accept': 'application/json',
'authorization':
'Basic U0ItTWlkLXNlcnZlci1kNnJNbGp5ZDBKSDgyOEhBT28tSWkxM0E=',
'cache-control': 'no-cache'
}
My Dart Function Snippet
Future _makePayment() async {
String url = "https://api.sandbox.midtrans.com/v2/charge";
final Map<String, String> header = {
'content-type': 'application/json',
'accept': 'application/json',
'authorization':
'Basic U0ItTWlkLXNlcnZlci1kNnJNbGp5ZDBKSDgyOEhBT28tSWkxM0E=',
'cache-control': 'no-cache'
};
var json = jsonEncode({
"payment_type": "bank_transfer",
"bank_transfer": {"bank": "permata", "va_number": "1234567890"},
"transaction_details": {
"order_id": "order-101b-{{2020-11-0222rrddzz557}}",
"gross_amount": 44000
},
"customer_details": {
"email": "richie#example.com",
"first_name": "Richie",
"last_name": "Permana",
"phone": "+6281 1234 1234"
},
"item_details": [
{
"id": "item01",
"price": 21000,
"quantity": 1,
"name": "Schema Programmer"
},
{"id": "item02", "price": 23000, "quantity": 1, "name": "Ayam Xoxoxo"}
]
});
Response response = await post(
url,
headers: header,
body: json,
);
var res = jsonDecode(response.body);
print(
"payloadddded =>> ${json.runtimeType}\n");
if (res['status_code'] == 201) {
print("ngeheeeee berhasil MIDTRAANSS =>> ${res['status_code']}");
} else {
print("res full =>> ${response.body}");
print("ape kaden => ${res['status_code']} || terosz => $res");
}
}
Note:
For the body, you may be need put more attention on the order_id because it will return some error if you not change the order_id (yes, think it like any other primary key id).
API Docs: https://api-docs.midtrans.com/
I really appreciate any helps or workaround given.
Thank you very much.
Dart's package:http manipulates the content-type header under the hood. If it does the encoding from string to bytes for you (i.e. if body is a string) then it adds a charset=xxx suffix to the content type - it becomes, for example application/json; charset=utf-8.
Apparently your server is allergic to this. (It shouldn't be, but whatever...). You can prove this using the dart:io http client.
var client = HttpClient();
var request = await client.postUrl(Uri.parse(url));
request.headers.set('content-type', 'application/json; charset=utf-8');
request.headers.add(
'authorization',
'Basic U0ItTWlkLXNlcnZlci1kNnJNbGp5ZDBKSDgyOEhBT28tSWkxM0E=',
);
request.add(utf8.encode(json));
var response2 = await request.close();
var reply = await response2.transform(utf8.decoder).join();
print(reply);
client.close();
This gives the same 408 error but does not if the charset suffix is removed.
There's a simple solution. Don't allow http to do the encoding for you - do it yourself.
var response = await http.post(
url,
headers: headers,
body: utf8.encode(json),
);
(Your json apparently needs work, because this now complains that the json is invalid, but that's easy to compare with your working postman.)

linkedin API cannot create campaign

We have got rw_ads permissions for an app. Through that app We have taken access_token with all given permissions.
As mentioned in the documentation, we have rw_ads permission, but If we try to create/update campaign we are getting the below error.
{
"serviceErrorCode": 100,
"message": "Not enough permissions to access: POST /adCampaignsV2/sdafnk",
"status": 403 }
var request = require("request");
var options = { method: 'POST',
url: 'https://api.linkedin.com/v2/adCampaignsV2/sdafnk',
headers:
{ 'Authorization': 'Bearer XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX',
'Content-Type': 'application/json' },
body:
{ patch:
{ '$set':
{ runSchedule: { end: 1548405000000, start: 1547713800000 },
status: 'ACTIVE' } } },
json: true };
request(options, function (error, response, body) {
if (error) throw new Error(error);
console.log(body);
});
Code for creation of campaign is mentioned below
var request = require("request");
var options = {
method: 'POST',
url: 'https://api.linkedin.com/v2/adCampaignsV2',
headers: {
'Authorization': 'Bearer <accessToken>',
'Content-Type': 'application/json'
},
body: {
account: 'urn:li:sponsoredAccount:<accountId>',
audienceExpansionEnabled: false,
costType: 'CPM',
creativeSelection: 'OPTIMIZED',
dailyBudget: { amount: '200', currencyCode: 'INR' },
locale: { country: 'IN', language: 'en' },
name: 'Campaign text ad test',
objectiveType: 'WEBSITE_TRAFFIC',
offsiteDeliveryEnabled: false,
runSchedule: { end: 1547708400000, start: 1547967600000 },
type: 'TEXT_AD',
unitCost: { amount: '10', currencyCode: 'INR' },
status: 'PAUSED'
},
json: true
};
request(options, function (error, response, body) {
if (error) throw new Error(error);
console.log(body);
});
When you perform a partial update, the header X-RestLi-Method must be included in the request and set to PARTIAL_UPDATE.
Also if you use implicit grant-type, check if you have defined the scope correctly at the start. if you use client-credentials grant-type check if the account has the right permissions.
Direct Sponsored Content can be created by:
Ad Account Users with a role higher than VIEWER. Organization users
with DIRECT_SPONSORED_CONTENT_POSTER or ADMINISTRATOR roles.
also the code you added in this question is for Reactivating a campaign. not for updating/creating one.

Issue with sending LiveChat messages via DDP in RocketChat

I am trying to use the DDP Realtime API to initiate a LiveChat conversation but I am facing issues.
https://rocket.chat/docs/developer-guides/realtime-api/livechat-api
I am doing all the steps as per the documentation. In the first API outcome, you can see that it saus numAgents: 2 and online: true. However when I try to send a message to the same department, it says: "Sorry, no online agents".
Is there a way to find out the problem?
Result of livechat:getInitialData
{ enabled: true,
title: 'xyz.com',
color: '#C1272D',
registrationForm: false,
room: null,
triggers: [],
departments:
[ { _id: 'CxCTgXL4csw3TcW6S',
enabled: true,
name: 'Support',
description: '',
numAgents: 2,
showOnRegistration: true,
_updatedAt: 2017-09-24T06:46:39.657Z } ],
allowSwitchingDepartments: true,
online: true,
offlineColor: '#666666',
offlineMessage: 'We are not online right now. Please leave us a message:',
offlineSuccessMessage: '',
offlineUnavailableMessage: '',
displayOfflineForm: true,
videoCall: true,
offlineTitle: 'Leave a message',
language: '',
transcript: false,
transcriptMessage: 'Would you like a copy of this chat emailed?' }
Result of livechat:registerGuest
{ userId: 'j65Cp5peeLJLYhWQi',
token: 'J8IpnpB1yN1AYtO0e0EzLhuaRhe0zaZkjHBAamsehSO' }
Result of Login
{ id: 'j65Cp5peeLJLYhWQi',
token: 'J8IpnpB1yN1AYtO0e0EzLhuaRhe0zaZkjHBAamsehSO',
tokenExpires: 2017-12-23T07:45:01.928Z }
Result of sendMessageLivechat
{ isClientSafe: true,
error: 'no-agent-online',
reason: 'Sorry, no online agents',
message: 'Sorry, no online agents [no-agent-online]',
errorType: 'Meteor.Error' }
These are the parameters I am sending to sendMessageLiveChat.
"_id" : "j65Cp5peeLJLYhWQi"
"rid" : "a_random_string"
"msg": "Hello"
"token" : "J8IpnpB1yN1AYtO0e0EzLhuaRhe0zaZkjHBAamsehSO"
Could someone help me?
This is how I called registerGuest.
ddpClient.call("livechat:registerGuest",[{"token":authToken,"name":"test1","email":"test2#gmail.com","department":department._id},25],function(err, info){
});
the token passed by me here is the admin's authToken
The ddpClient object is obtained using the DDP npm package.
I solved this by a combination of
setting the bot as livechat agent & manager at the same time (I've read that tip somewhere it might be nonsense)
in Admin -> Omnichannel -> routing I've set 'accept even when no agents are online' (since my bot was never online, bould it was replying when DMessaged) + 'assign bot agents to new conversations'
I've setup myself a livechat-manager + livechat-agent role, but stayed in a different department, that way I can takeover
The rocket chat live api docs are quite out of date, just got stream-room-messages working because of a random forum post. Generally, registerGuest works with very minimal parameters as well, namely a random, self generated token + a name.
Here's my code for the complete setup
async subscribeToLiveRoom(message){
var _self = this
// let initial = await this.api
// .call("livechat:getInitialData",[token])
// register
const token = this.randomString()
var guestUser = await this.api
.call(
'livechat:registerGuest',
[{
token: token,
name: _self.$auth.user.name
}]
)
.catch(console.error)
console.log('guest', guestUser.visitor.token)
this.setActiveGuest(guestUser)
var roomId = this.randomString()
this.setActiveRoom(roomId)
let msg = await this.api
.call(
'sendMessageLivechat',
[{
_id: _self.randomString(),
rid: roomId,
msg: message,
token: guestUser.visitor.token
}])
.catch(console.error)
try {
let liveStream = await this.$subscribe("stream-livechat-room",[
roomId,
{
"useCollection": true,
"args":[
{
"visitorToken": guestUser.visitor.token
}
]
}
])
this.msgLive = await this.find('stream-livechat-room')
} catch (e) {
console.log(e)
}
//
try {
var roomStream = await this.$subscribe("stream-room-messages",[
roomId,
{
"useCollection": true,
"args":[
{
"visitorToken": guestUser.visitor.token
}
]
}
])
console.log('roomstream')
var update = this.find('stream-room-messages')
} catch (e) {
console.log('an error occured', e)
}
console.log( this.msg)
},
async sendToLiveRoom(message, rId){
var _self = this
// let initial = await this.api
// .call("livechat:getInitialData",[token])
// register
let msg = await this.api
.call(
'sendMessageLivechat',
[{
_id: _self.randomString(),
rid: rId,
msg: message,
token: _self.guest.visitor.token
}])
.catch(console.error)
},
By the way, since it's not well documented, you will get room-messages in livechat rooms via subscribing to stream-room-messages while you get room status changes (like switched to another agent) by subscribing to stream-livechat-room

HTTP.post to FCM Server not working

I am using Ionic 2 with HTTP native module to make a post request to FCM server for push notifications. The code I am using is:
HTTP.post(
"https://fcm.googleapis.com/fcm/send",
{
"notification": {
"title": "Notification title",
"body": "Notification body",
"sound": "default",
"click_action": "FCM_PLUGIN_ACTIVITY",
"icon": "fcm_push_icon"
},
"data": {
"hello": "This is a Firebase Cloud Messagin hbhj g Device Gr new v Message!",
},
"to": "device token",
},
{
Authorization: {
key: "AUTHORIZATION KEY HERE"
}
})
Its giving me an error:
Unimplemented console API: Unhandled Promise rejection:
Unimplemented console API: Error: Uncaught (in promise): [object Object]
I tried the post request with Postman, it works perfectly fine delivering push notifications.
The code with Postman is:
POST /fcm/send HTTP/1.1
Host: fcm.googleapis.com
Content-Type: application/json
Authorization: key=Authorisation Key
Cache-Control: no-cache
Postman-Token: 446e253b-179a-d19b-21ea-82d9bb5d4e1c
{
"to": "Device Token",
"data": {
"hello": "This is a Firebase Cloud Messagin hbhj g Device Gr new v Message!",
}
"notification":{
"title":"Notification title",
"body":"Notification body",
"sound":"default",
"click_action":"FCM_PLUGIN_ACTIVITY",
"icon":"fcm_push_icon"
},
}
Questions:
I am unable to add content-type to the header in the HTTP post request, but it works with postman.
If I try to add a function(response) { to get the response from the server, it gives me an error. The documentation for the same is at https://github.com/wymsee/cordova-HTTP
why are you using HTTP native module? Angular has a built in Http.
Using this one (importing HttpModule from #angular/http in your NgModule) you can just call
import { Http, Headers } from '#angular/http';
......
constructor(public http: Http) { }
sendPushNotification(deviceId: string) {
let url = 'https://fcm.googleapis.com/fcm/send';
let body =
{
"notification": {
"title": "Notification title",
"body": "Notification body",
"sound": "default",
"click_action": "FCM_PLUGIN_ACTIVITY",
"icon": "fcm_push_icon"
},
"data": {
"hello": "This is a Firebase Cloud Messagin hbhj g Device Gr new v Message!",
},
"to": "device token"
};
let headers: Headers = new Headers({
'Content-Type': 'application/json',
'Authorization': 'key='+this.someKey
});
let options = new RequestOptions({ headers: headers });
console.log(JSON.stringify(headers));
this.http.post(url, body, headers).map(response => {
return response;
}).subscribe(data => {
//post doesn't fire if it doesn't get subscribed to
console.log(data);
});
}
push.on('notification', (data) => {
if (data.additionalData.foreground) {
// if application open, show popup
let confirmAlert = this.alertCtrl.create({
title: data.title,
message: data.message,
buttons: [{
text: 'Ignore',
role: 'cancel'
}, {
text: 'Go to',
handler: () => {
//TODO: Your logic here
this.navCtrl.setRoot(EventsPage, {message: data.message});
}
}]
});
confirmAlert.present();
} else {
//if user NOT using app and push notification comes
//TODO: Your logic on click of push notification directly
this.navCtrl.setRoot(EventsPage, {message: data.message});
}
});
push.on('error', (e) => {
alert(e);
});
});

Resources