We have been using Firebase to send push notifications for a couple of months in our app, and I have used it in other of my apps . Everything had gone well, however a week ago we started receiving duplicate notifications (not always). The strange thing is that we did not change any code, it just started to happen in both Android and iOS. It only happens sometimes not always, and only in some users/devices.
I want to know if someone else is going through this with Firebase. I think it is a Firebase bug but I would like to see if someone can confirm something about it.
The ios app is made in swift, and the android app in Java.
BTW. We are sending it based on this with FCM in our back-end. And we have no duplicated topics. I have checked and devices are only subscribed once.
https://fcm.googleapis.com/fcm/send
Content-Type:application/json
Authorization:key=AIzaSyZ-1u...0GBYzPu7Udno5aA
{
"to": "/topics/foo-bar",
"data": {
"message": "This is a Firebase Cloud Messaging Topic Message!",
}
}
Here my c# code in our back-end to send notifications
public void sendPushNotification(string _title, string _message, string _topic, object customData = null)
{
var requestUri = "https://fcm.googleapis.com/fcm/send";
WebRequest webRequest = WebRequest.Create(requestUri);
webRequest.Method = "POST";
webRequest.Headers.Add(string.Format("Authorization: key={0}", FCM_SERVER_API_KEY));
webRequest.Headers.Add(string.Format("Sender: id={0}", FCM_SENDER_ID));
webRequest.ContentType = "application/json";
var data = new
{
to = "/topics/" + _topic, // this is for topic
notification = new
{
title = _title,
body = _message,
sound = "default"
},
data = customData, //custom data (got it from firebase documentation)
content_available = true
};
var serializer = new JavaScriptSerializer();
var json = serializer.Serialize(data);
Byte[] byteArray = Encoding.UTF8.GetBytes(json);
webRequest.ContentLength = byteArray.Length;
using (Stream dataStream = webRequest.GetRequestStream())
{
dataStream.Write(byteArray, 0, byteArray.Length);
using (WebResponse webResponse = webRequest.GetResponse())
{
using (Stream dataStreamResponse = webResponse.GetResponseStream())
{
using (StreamReader tReader = new StreamReader(dataStreamResponse))
{
String sResponseFromServer = tReader.ReadToEnd();
}
}
}
}
}
Related
I have the project in asp.net MVC 5 I need to add all option to my client-side app
which is send a push notification to android and ios app
for this scenario, I had created a page like a firebase cloud messaging =>
create message
c# code
private static string SendPushNotification()
{
string response;
try
{
string serverKey = "##########";
string senderId = "#############";
string deviceId = "//topics/all";
WebRequest tRequest = WebRequest.Create("https://fcm.googleapis.com/fcm/send");
tRequest.Method = "post";
tRequest.ContentType = "application/json";
var data = new
{
to = deviceId,
notification = new
{
body = "Greetings",
title = "Augsburg",
sound = "Enabled"
}
};
var serializer = new JavaScriptSerializer();
var json = serializer.Serialize(data);
Byte[] byteArray = Encoding.UTF8.GetBytes(json);
tRequest.Headers.Add(string.Format("Authorization: key={0}", serverKey));
tRequest.Headers.Add(string.Format("Sender: id={0}", senderId));
tRequest.ContentLength = byteArray.Length;
using (Stream dataStream = tRequest.GetRequestStream())
{
dataStream.Write(byteArray, 0, byteArray.Length);
using (WebResponse tResponse = tRequest.GetResponse())
{
using (Stream dataStreamResponse = tResponse.GetResponseStream())
{
using (StreamReader tReader = new StreamReader(dataStreamResponse))
{
String sResponseFromServer = tReader.ReadToEnd();
response = sResponseFromServer;
}
}
}
}
}
catch (Exception ex)
{
response = ex.Message;
}
return response;
}
So My query is that
1: I could send all these options to my HTTP request or not
2: There is open to send later open I need to also configure this
option
3: And Target User option?
Could I do this using HTTP request by providing parameters?
Not all.For most of the text fields, you can (see the docs for the HTTP ref):
Message Text = body
Message label: Nope. See the help text (?), it's just a label that the Firebase Console uses.
Delivery Date: See #2.
User Segment: See #3.
Message title = title
Android Notification Channel Name = android_channel_id
Scheduled notifications are currently not available for the REST API.
User Segments currently not available yet.
I am writing a c# service that will allow me to send push notifications using FCM. Now, everything works fine but then I want to send bulk push notification using FCM.
I want to be able to send the same message to multiple devices at once. The current takes one registration token and then goes through the whole process and then goes to the next one. But this will be useless if I have to send push notification to many numbers at once. What should be my best option?
c# code
public String SendPushNotification(string regtoken)
{
try
{
string applicationID = "#############3";
string senderId = "##########";
string deviceId = regtoken;
WebRequest tRequest = WebRequest.Create("https://fcm.googleapis.com/fcm/send");
tRequest.Method = "post";
tRequest.ContentType = "application/json";
var data = new
{
to = deviceId,
notification = new
{
body = message,
title = "",
sound = ""
}
};
var serializer = new JavaScriptSerializer();
var json = serializer.Serialize(data);
Byte[] byteArray = Encoding.UTF8.GetBytes(json);
tRequest.Headers.Add(string.Format("Authorization: key={0}", applicationID));
tRequest.Headers.Add(string.Format("Sender: id={0}", senderId));
tRequest.ContentLength = byteArray.Length;
using (Stream dataStream = tRequest.GetRequestStream())
{
dataStream.Write(byteArray, 0, byteArray.Length);
using (WebResponse tResponse = tRequest.GetResponse())
{
using (Stream dataStreamResponse = tResponse.GetResponseStream())
{
using (StreamReader tReader = new StreamReader(dataStreamResponse))
{
String sResponseFromServer = tReader.ReadToEnd();
String str = sResponseFromServer;
}
}
}
status = statusmessages();
}
}
catch (Exception ex)
{
string str = ex.Message;
status = "failure";
}
return status;
}
Update: For v1, it seems that registration_ids is no longer supported and that making use of topics is the best approach.
You can either use the registration_ids parameter where you'll be able to specify up to 1000 registration tokens:
This parameter specifies the recipient of a multicast message, a message sent to more than one registration token.
The value should be an array of registration tokens to which to send the multicast message. The array must contain at least 1 and at most 1000 registration tokens. To send a message to a single device, use the to parameter.
Just replace
to = deviceId
to something like
registration_ids = deviceIds
where deviceIds is an array of tokens.
Or you could make use of Topic Messaging, where so long as the user is subscribed to your given topic, they would receive messages sent to that topic.
In order to send a notification from an Console App to an android device I am using the following code:
class Program
{
static void Main(string[] args)
{
string applicationId = "applicationId";
string senderId = "senderId";
string deviceId = "deviceId";
string message = "TestMessage";
var x = new AndroidFCMPushNotificationStatus();
var response = x.SendNotification(applicationId, senderId, deviceId, message);
Console.WriteLine(response);
Console.ReadLine();
}
}
and
public class AndroidFCMPushNotificationStatus
{
public string SendNotification(string applicationID, string senderId, string deviceId, string message)
{
try
{
WebRequest tRequest = WebRequest.Create("https://fcm.googleapis.com/fcm/send");
tRequest.Method = "post";
tRequest.ContentType = "application/json";
var data = new
{
to = deviceId,
notification = new
{
body = message,
title = message,
},
priority = "high"
};
var serializer = new JavaScriptSerializer();
var json = serializer.Serialize(data);
Byte[] byteArray = Encoding.UTF8.GetBytes(json);
tRequest.Headers.Add(string.Format("Authorization: key={0}", applicationID));
tRequest.Headers.Add(string.Format("Sender: id={0}", senderId));
tRequest.ContentLength = byteArray.Length;
using (Stream dataStream = tRequest.GetRequestStream())
{
dataStream.Write(byteArray, 0, byteArray.Length);
using (WebResponse tResponse = tRequest.GetResponse())
{
using (Stream dataStreamResponse = tResponse.GetResponseStream())
using (StreamReader tReader = new StreamReader(dataStreamResponse))
{
string sResponseFromServer = tReader.ReadToEnd();
return (sResponseFromServer);
}
}
}
}
catch (Exception ex)
{
return (ex.Message);
}
}
}
from Push Notification C#.
I created a firebase console project and from the project settings, from the tab Cloud Messaging I got the Server Key and Sender Id (in code they are the applicationId and senderId). I also got my device Id from an app I downloaded to my mobile, where it gives me a string under the label Android Device Id.
However I get the message error:InvalidRegistration.
I am pretty new to this and I think I am missing something.
Is the above code supposed to work and whenever I run the program I should get a notification on my phone?
Should I do anything to allow this notifications to my mobile? I haven't configured anything on my device.
The idea is to pack this code in a service and whenever something is happening on the server I want to use this code in order to inform
my device. Is this the correct way?
Thank you in advance.
error:InvalidRegistration means that the deviceId (also called Registration token) is wrong.
Check the format of the registration token you pass to the server.
Make sure it matches the registration token the client app receives
from registering with Firebase Notifications. Do not truncate or add
additional characters.
https://firebase.google.com/docs/cloud-messaging/http-server-ref#error-codes
check that you are reading the correct token:
FirebaseInstanceId.getInstance().getToken()
https://firebase.google.com/docs/cloud-messaging/android/first-message#retrieve-the-current-registration-token
I am using FCM Notifications in my android app.
the notification has to be sent to sent to a limited number of users (around 200 users) at the same time using .net pages
public static void SendPushNotification()
{
try
{
string applicationID = "ABC****xyz";
string senderId = "01*****89";
string deviceId1 = "def****jdk";
string deviceId2 = "lej****wka";
string deviceId3 = "fqx****pls";
WebRequest tRequest = WebRequest.Create("https://fcm.googleapis.com/fcm/send");
tRequest.Method = "post";
tRequest.ContentType = "application/json";
var data = new
{
//This line is the problem
to = deviceId1+","+deviceId2+","+deviceId3,
notification = new
{
body = "Notification Body",
title = "Notification Title",
sound = "Enabled",
icon = "MyIcon"
}
};
var serializer = new JavaScriptSerializer();
var json = serializer.Serialize(data);
Byte[] byteArray = Encoding.UTF8.GetBytes(json);
tRequest.Headers.Add(string.Format("Authorization: key={0}", applicationID));
tRequest.Headers.Add(string.Format("Sender: id={0}", senderId));
tRequest.ContentLength = byteArray.Length;
using (Stream dataStream = tRequest.GetRequestStream())
{
dataStream.Write(byteArray, 0, byteArray.Length);
using (WebResponse tResponse = tRequest.GetResponse())
{
using (Stream dataStreamResponse = tResponse.GetResponseStream())
{
using (StreamReader tReader = new StreamReader(dataStreamResponse))
{
String sResponseFromServer = tReader.ReadToEnd();
string str = sResponseFromServer;
}
}
}
}
}
catch (Exception ex)
{
string str = ex.Message;
}
}
The to line is problem is where I concatenate multiple devices
How can I just send the notifications for these devices?
Thanks
For sending push notification to multiple devices, you have to use 'registration_ids' instead of 'to' parameter that contains array of device tokens. The limitation is that you can provide a maximum of 1000 device tokens by this method. Check this out for reference FCM Downstream Messages
I am using FCM in my Android and iOS app. The client side code is working correctly because from the Firebase console I can send notifications to both platforms with out any problem. With my C# code I can send notifications successfully to android devices but the notifications never appear on iPhone unless directly coming from the Firebase notification console. I don't know what gives.
C# server-side code
try
{
var applicationID = "application_id";
var senderId = "sender_id";
string deviceId = "device_id_of_reciever";
WebRequest tRequest = WebRequest.Create("https://fcm.googleapis.com/fcm/send");
tRequest.Method = "post";
tRequest.ContentType = "application/json";
var data = new
{
to = deviceId,
notification = new
{
body = "This is the message",
title = "This is the title",
icon = "myicon"
}
};
var serializer = new JavaScriptSerializer();
var json = serializer.Serialize(data);
Byte[] byteArray = Encoding.UTF8.GetBytes(json);
tRequest.Headers.Add(string.Format("Authorization: key={0}", applicationID));
tRequest.Headers.Add(string.Format("Sender: id={0}", senderId));
tRequest.ContentLength = byteArray.Length;
using (Stream dataStream = tRequest.GetRequestStream())
{
dataStream.Write(byteArray, 0, byteArray.Length);
using (WebResponse tResponse = tRequest.GetResponse())
{
using (Stream dataStreamResponse = tResponse.GetResponseStream())
using (StreamReader tReader = new StreamReader(dataStreamResponse))
{
String sResponseFromServer = tReader.ReadToEnd();
Response.Write(sResponseFromServer);
}
}
}
}
catch (Exception ex)
{
Response.Write(ex.Message);
}
Notifications are not working on iPhone with my server side code but I get a good response from Firebase.
{
"multicast_id": 479608 XXXXXX529964,
"success": 1,
"failure": 0,
"canonical_ids": 0,
"results": [{
"message_id": "0:1467935842135743%a13567c6a13567c6"
}]
}
Any help or suggestions would be really appreciated.
Try setting the priority field to High in your FCM request.
Eg:
var data = new
{
to = deviceId,
notification = new
{
body = "This is the message",
title = "This is the title",
icon = "myicon"
},
priority = "high"
};
Note though that using high priority in development is fine but in production it should only be used when the user is expected to take action, like reply to a chat message.
I am using FCM in android and IOS push notification.I am using Visual Studio 2015.To be create a web api project and a to add a controller.write the code.Code is given below
using System;
using System.Net;
using System.Web.Http;
using System.Web.Script.Serialization;
using System.Configuration;
using System.IO;
namespace pushios.Controllers
{
public class HomeController : ApiController
{
[HttpGet]
[Route("sendmessage")]
public IHttpActionResult SendMessage()
{
var data = new {
to = "device Tokens", // iphone 6s test token
data = new
{
body = "test",
title = "test",
pushtype="events",
},
notification = new {
body = "test",
content_available = true,
priority= "high",
title = "C#"
}
} ;
SendNotification(data);
return Ok();
}
public void SendNotification(object data)
{
var Serializer = new JavaScriptSerializer();
var json = Serializer.Serialize(data);
Byte[] byteArray = System.Text.Encoding.UTF8.GetBytes(json);
SendNotification(byteArray);
}
public void SendNotification(Byte[] byteArray)
{
try
{
String server_api_key = ConfigurationManager.AppSettings["SERVER_API_KEY"];
String senderid = ConfigurationManager.AppSettings["SENDER_ID"];
WebRequest type = WebRequest.Create("https://fcm.googleapis.com/fcm/send");
type.Method = "post";
type.ContentType = "application/json";
type.Headers.Add($"Authorization: key={server_api_key}");
type.Headers.Add($"Sender: id={senderid}");
type.ContentLength = byteArray.Length;
Stream datastream = type.GetRequestStream();
datastream.Write(byteArray, 0, byteArray.Length);
datastream.Close();
WebResponse respones = type.GetResponse();
datastream = respones.GetResponseStream();
StreamReader reader = new StreamReader(datastream);
String sresponessrever = reader.ReadToEnd();
reader.Close();
datastream.Close();
respones.Close();
}
catch (Exception)
{
throw;
}
}
}
}
In the case of android json is given below
var data = new {
to = "device Tokens", // iphone 6s test token
data = new
{
body = "test",
title = "test",
pushtype="events",
};
In the case of IOS json
var data = new {
to = "device Tokens", // iphone 6s test token
data = new
{
body = "test",
title = "test",
pushtype="events",
},
notification = new {
body = "test",
content_available = true,
priority= "high",
title = "C#"
}
} ;
SERVER_API_KEY,SENDER_ID I am adding the web config.To be collect SERVER_API_KEY,SENDER_ID in FCM.
<add key="SERVER_API_KEY" value="ADD Key in FCM"/>
<add key="SENDER_ID" value="Add key in fcm "/>