Figuring out which FCM tokens are expired from a firebase response with several registration ids - firebase-cloud-messaging

Firebase rest endpoint for push notifications lets you send a message to several people at once by passing the tokens through "registration_ids" array instead of "to". When the response comes back it looks like this:
{
"multicast_id":000000000000000000,
"success":1,
"failure":4,
"canonical_ids":0,
"results":[
{
"error":"NotRegistered"
},
{
"error":"NotRegistered"
},
{
"error":"NotRegistered"
},
{
"error":"NotRegistered"
},
{
"message_id":"0:0000000000000000%a0a0a0aaa0a0a0aa"
}
]
}
How are you supposed to correlate the NotRegistered errors to a particular token it was sent to?

The results are in the same order as you specified them in the request. So only your last token was valid.

Related

WhatsApp Business Platform API using Test account doesn't send the message to Mobile

I have created a WhatsApp Business Platform Test account. I am able to send and receive the hello-world template message but when I send a test message without template(as specified by the api) it doesn't push it to the mobile phone. Strangely I get success response in both cases.
Url: https://graph.facebook.com/v15.0/11ZZZZZZZZZZZZZ/messages
Here are the jsons and their responses
{
"messaging_product":"whatsapp",
"to":"91ZZZZZZZZZZ",
"type":"template",
"template":{
"name":"hello_world",
"language":{
"code":"en_US"
}
}
}
{
"messaging_product":"whatsapp",
"contacts":[
{
"input":"91ZZZZZZZZZZ",
"wa_id":"91ZZZZZZZZZZ"
}
],
"messages":[
{
"id":"wamid.HBgMOTE3MjkwMDIxMzYwFQIAERgSMjZCRkQ3RDc0RjM0QkNEZZZZZZ=="
}
]
}
In these case I successfully receive message on the mobile
{
"messaging_product":"whatsapp",
"to":"91ZZZZZZZZZZ",
"type":"text",
"text":{
"preview_url":false,
"body":"Hello World Testing"
}
}
{
"messaging_product":"whatsapp",
"contacts":[
{
"input":"91ZZZZZZZZZZ",
"wa_id":"91ZZZZZZZZZZ"
}
],
"messages":[
{
"id":"wamid.HBgMOTE3MjkwMDIxMzYwFQIAERgSQUJERkM2RUE1RTEwQTExZZZZZZ=="
}
]
}
However I don't receive message on the mobile.
Is there anything I am missing in the second case?
I was strugging with the same problem, but I figured out that you need to reply back to your first template message with a 'hello' or any kind of reply. Once you reply, only then can you send a message through that watsapp api without a template, or you can inititate conversation through watsapp api.
Hope this answer helps you.

Attempting to subscribe to a Shopify Webhook w/AWS EventBridge produces error: "Address is an AWS ARN and includes api_client_id 'x' instead of 'y'"

I'm running this request through Postman. Some posts to the Shopify developer forum (e.g., this one) express without clear explanation that the request should be made within the Shopify app that would be subscribing to the Webhooks, but Postman seems to work, too.
In Postman . . .
Here's the endpoint:
https://{{shopifyDevelopmentStoreName}}.myshopify.com/admin/api/2022-07/graphql.json
Here's the GraphQL body:
mutation createWebhookSubscription($topic: WebhookSubscriptionTopic!, $webhookSubscription: EventBridgeWebhookSubscriptionInput!) {
eventBridgeWebhookSubscriptionCreate(
topic: $topic,
webhookSubscription: $webhookSubscription
) {
webhookSubscription {
id
}
userErrors {
message
}
}
}
Here's the payload being sent (notice the "client_id_x" value within the arn property):
{
"topic": "PRODUCTS_CREATE",
"webhookSubscription": {
"arn": "arn:aws:events:us-east-1::event-source/aws.partner/shopify.com/client_id_x/LovecraftEventBridgeSource",
"format": "JSON",
"includeFields": "id"
}
}
Here's the response I receive:
{
"data": {
"eventBridgeWebhookSubscriptionCreate": {
"webhookSubscription": null,
"userErrors": [
{
"message": "Address is invalid"
},
{
"message": "Address is an AWS ARN and includes api_client_id 'client_id_x' instead of 'client_id_y'"
}
]
}
},
"extensions": {
"cost": {
"requestedQueryCost": 10,
"actualQueryCost": 10,
"throttleStatus": {
"maximumAvailable": 1000.0,
"currentlyAvailable": 990,
"restoreRate": 50.0
}
}
}
}
What's entirely unclear is why Shopify is insisting upon validity of "client_id_y" when, in AWS, the value being displayed is undeniably 'client_id_x'. Extremely confusing. I don't even see what difference using the Shopify app would make except that it produces a client_id value that works counter to one's expectations and intuitions.
Does anyone know why the heck Shopify isn't just using the client_id value of the event bus created earlier in Amazon EventBridge?
Same happend to me and I was lucky to find a solution.
The error message is just missleading.
I replaced the API Access Token for the Shopify Rest API Request (X-Shopify-Access-Token)
with the one from the Shopify App holding the aws credentials.
admin/settings/apps/development -> app -> API credentials -> Admin API access token. (can only be seen after creation)
Then I could subscribe webhooks to the app via the Rest Interface.

How to Handle push notification when sent to multiple device but some them are failed

I want to send fcm push notifications to android and ios app. I am using this code to send
let message = {
registration_ids: firebaseId, // this is the array of tokens
collapse_key: 'something',
data: {
type: data.type,
title: data.title,
body : data.body,
notificationId: something
},
};
fcm.send(message, (err, response) => {
if (err) {
console.log(err);
resolve(false);
} else {
console.log("Notification Android Sent Successfully");
console.log(response);
}
});
Now what I want if some notifications are failed then I want to send them SMS. but I got a response like this form the fcm server in case of success or failure.
Notification Android Sent Successfully
{"multicast_id":7535512435227354255,"success":2,"failure":1,"canonical_ids":0,"results":[{"message_id":"0:1610622370449056%d0bd483c86f03759"},{"message_id":"0:1610622370449058%d0bd483c86f03759"},{"error":"InvalidRegistration"}]}
now how will I know which device did not get the notification as we can see there 1 failure from 3 device
so i can send SMS to that device
The results in the response you get contains the result for each token, in the same order in which you specified them,
So in your example, the message was successfully sent to the first two tokens, while the third token was unknown. You'll want to remove that last token from your database to prevent trying to send messages to it in the future.

Email only authentication with Vue.js and Vuex on Firebase

I want user to be automatically authenticated (temporarily) on Firebase just by sending Email then be redirected to a welcome page asking to complete the auth process by following a link received by email.
The first part is ok, I can authenticate by just inserting email and generating a random password like the following (Vuex store action):
this.$store.dispatch('userSignUp', { email: this.email, password: this.generatePassword })
which is called by component method button v-on:click="userSignUp
Vuex action is like :
userSignUp ({commit}, payload) {
commit('setLoading', true)
firebase.auth().createUserWithEmailAndPassword(payload.email, payload.password)
.then(firebaseUser => {
commit('setUser', firebaseUser)
commit('setLoading', false)
commit('setError', null)
router.push('/welcome')
})
.catch(error => {
commit('setError', error.message)
commit('setLoading', false)
})
}
So far so good, the user put the email, an helper function this.generatePassword generate a random password and the user is logged in and created on firebase.
Now this user is logged in, is on a welcome page, but it doesn't know his own random password (because I don't want to).
I want this to be one shot login and if the user want to come back, has to follow the link sent by email by Firebase.
There is a firebase function [sendPasswordResetEmail][1], which seems right for the case but I connot find the way to make it working.
I did Vuex action like before :
export const actions = {
sendPasswordReset ({commit}, payload) {
commit('setLoading', true)
firebase.auth().sendPasswordResetEmail(payload.email)
.then(firebaseUser => {
commit('setUser', firebaseUser)
commit('setLoading', false)
commit('setError', null)
router.push('/welcome')
})
.catch(error => {
commit('setError', error.message)
commit('setLoading', false)
router.push('/error')
})
},
...
which is called by component method button v-on:click="userSignUp
methods: {
userSignUp () {
this.$store.dispatch('userSignUp', { email: this.email, password: this.generatePassword })
this.$store.dispatch('sendPasswordReset', { email: this.email })
}
},
I only get response code
{
"error": {
"errors": [
{
"domain": "global",
"reason": "invalid",
"message": "EMAIL_NOT_FOUND"
}
],
"code": 400,
"message": "EMAIL_NOT_FOUND"
}
}
while the Request Payload seems ok anyway :
{requestType: "PASSWORD_RESET", email: "luca.soave#gmail.com"}
email
:
"luca.soave#gmail.com"
requestType
:
"PASSWORD_RESET"
Any idea ?
The provider you're using is called the password provider. As its name implies it is heavily dependent on the user having (and knowing) a password. Since you are looking for passwordless authentication, I'd recommend against using the email+password provider as the basis.
Instead consider implementing a custom authentication provider. While this involves a few more components, it is not as difficult as you may think. You'll need to run trusted code, which you can do either on a server you already have, or on Cloud Functions. In either of those cases, you'll use one of the Admin SDKs to implement the sensitive parts of the authentication flow.
A quick list of steps that I think you'll need:
Create an endpoint (e.g. a HTTP triggered Cloud Function) for the user to request an authentication email.
Implement the code for this endpoint to:
Generate a random one-time code in there, which you're going to send to the user. Firebase Authentication calls this the out-of-band (or OOB) code, since it's sent to the user on a different medium than your app.
Store this code and the user's email address somewhere where only your server-side code can read it, e.g. in the Firebase Database or Cloud Firestore.
Send an email to the user, with the code or a link to a page that includes the code and their email address.
Create an endpoint (e.g. again a HTTP function, or web page) where the user enters (e.g. by clicking on a link in the email) the OOB code and their email address.
Compare the code the user entered, to the one you stored before.
If the codes match, generate a custom token for the user and send it to them.
The user/app now signs into Firebase with the custom token.

Pushwoosh can not delete message created by API

EDIT: as noted in the answer below, this was a problem on the pushwoosh side, it has been fixed!
When I create a push message through the pushwoosh API (using /createTargetedMessage) I'm not able to delete the message through the API. Messages made with the pushwoosh interface can be deleted through the API, no prob...
These are the steps I took to produce this error:
1. Create push message with the following params
{
"request":{
"auth":"AUTH TOKEN",
"send_date":"2015-09-22 15:07",
"content":{
"nl":"teststsdfgh",
"en":"teststsdfgh"
},
"devices_filter":"A(\"8A1EB-4E875\") * T(\"inholidaypark\", BETWEEN, [\"2015-09-22 00:00\",\"2015-09-22 23:59\"]) * T(\"Language\", IN, [\"nl\", \"en\"])"
}
}
2. This returns the following response; the messageCode is stored in our local DB for later use
{
"status":200,
"response":{
"status_code":200,
"status_message":"OK",
"response":
"messageCode":"D3F6-60769243-68B30EA8"
}
}
}
3. Call /deleteMessage with following data
{
"request":{
"auth":"AUTH TOKEN",
"message": "D3F6-60769243-68B30EA8"
}
}
4. API keeps returning:
{
"status_code": 210,
"status_message": "Message not found",
"response": null
}
But when I look at the push history the message is there (with the same messageCode and all). And it can be deleted through the pushwoosh interface, but not through the API.
On a side note: when the message is sent, we can obviously no longer delete it, then the API returns a more or less correct error:
{
"status_code": 210,
"status_message": "Forbidden",
"response": null
}
Just FYI for the rest of the readers, this issue has been identified and fixed on Pushwoosh side.
Move Along, Nothing to See Here. :)