I am trying to send FCM notification to a particular device after some data is saved to database. However, the notification cannot be received by my mobile app running in Android emulator and built with Flutter.
I tested the same registration token from FCM console and the notification can be received.
Here is my implementation in my C#
using FirebaseAdmin.Messaging;
using Google.Apis.Auth.OAuth2;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
namespace MyNeighbours.Server.Infrastructure.Services
{
public class FirebaseService : IFirebaseService
{
public FirebaseService()
{
FirebaseApp.Create(new AppOptions()
{
Credential = GoogleCredential.FromFile(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "firebase-private-key.json")),
});
}
public async Task<string> SendNotification(IEnumerable<string> fcmRegistrationTokens, string title, string body)
{
Message message = new Message()
{
Token = "some valid token",
Data = new Dictionary<string, string>()
{
{"title", title},
{"body", body},
},
};
var response = await FirebaseMessaging.DefaultInstance.SendAsync(message);
return response;
}
}
}
Every time when I send a notification, response always shows succeeded with a message id. I can also confirm the private key json file is loaded.
Can anyone please help? Thank you
try to add Notification in Message{} and set sound and priority:
Notification = new Notification()
{
Title = Title,
Body = Body
},
Android = new AndroidConfig()
{
Notification = new AndroidNotification()
{
Sound = "default",
Priority = NotificationPriority.MAX
}
},
Apns = new ApnsConfig()
{
Aps = new Aps()
{
Sound = "default"
}
}
Related
I am using PushSharp HTTP2 library to send the notification. Notification is working perfectly fine in English but when I send in Arabic, I receive it as question marks "??????????"
string message="test";
notificationModel.APS.Add("alert", message.Substring(0, Math.Min(message.Length, 160)));
notificationModel.APS.Add("badge", currentUnReadCount);
notificationModel.APS.Add("type", type);
notificationModel.APS.Add("sound", ringtone);
notificationModel.APS.Add("notification-id", notification.Id);
notificationModel.APS.Add("milestone-prize", MilestoneRedeem);
notificationModel.APS.Add("redirect_action", notification.WebUrl);
ApnsHttp2Notification appleNotification = new ApnsHttp2Notification
{
DeviceToken = currDevice.AppPushToken,
Payload = JObject.Parse(JsonConvert.SerializeObject(notificationModel)),
Tag = new PushNotificationAudience()
{
PushNotificationId = notification.Id,
UserDeviceId = currDevice.Id,
IsRead = false
},
Topic = certificate.BundleId,
};
iOsBroker.QueueNotification(appleNotification);
I am using POST method to send the SMS using PLIVO but the problem is I need to know the Request bytes before sending from another tool which is Arduino . I could see in the Response debugger that Request.ContentLenght is 156 but this is not correct when we are supplying the bytes in Arduino
Please check the below code for Reference I need to know the Request with Payload size in bytes
using Plivo;
using Plivo.API;
using RestSharp;
using System;
using System.Collections.Generic;
namespace PlivoSMSApp
{
class Program
{
static void Main(string[] args)
{
Program obj = new Program();
bool isSMSSent = obj.SendSms("+91852762678", "+420603797597", "Send SMS using Plivo");
}
public bool SendSms(string from, string to, string text)
{
string authId = "TestAuthID";
string autoToken = "TestAuthToken";
RestAPI plivo = new RestAPI(authId, autoToken);
IRestResponse resp = plivo.send_message(new Dictionary<string, string>()
{
{ "src", ""+from+"" }, // Sender's phone number with country code
{ "dst", ""+to+"" }, // Receiver's phone number with country code
{ "text", ""+text+"" }, // Your SMS text message
// To send Unicode text
// {"text", "こんにちは、元気ですか?"} // Your SMS text message - Japanese
// {"text", "Ce est texte généré aléatoirement"} // Your SMS text message - French
{ "url", "http://google.com/delivery_report"}, // The URL to which with the status of the message is sent
{ "method", "POST"} // Method to invoke the url
});
if (!String.IsNullOrEmpty(resp.ErrorMessage))
return false;
return true;
}
}
}
I have built an app that needs to connect to a Bot DirectLine - websockets channel to interact in conversations via LUIS and sms with Twilio.
To make the bot talk to the app I wrote a mvc controller that relays messages.
I am not sure this approach is correct, I made it up from some samples.
It works, but the main problem is that my code seems to always start a new conversation when a message is received from the client, so the context is not maintained.
How can I keep the conversation flowing and not restarting at every message?
I mean, the steps should be, for example:
Bot: Hello, what's your name?
User: Carl
Bot: Pleased to meet you Carl!
instead I get:
Bot: Hello, what's your name?
User: Carl
Bot: Sorry, I can't help you with that.
like the conversation is restarted from scratch.
Here is my controller code (the Twilio webhook is set to https://mySmsMVCapp.azurewebsites.net/smsapp/):
public class smsappController : TwilioController
{
private static string directLineSecret = ConfigurationManager.AppSettings["DirectLineSecret"];
private static string botId = ConfigurationManager.AppSettings["BotId"];
const string accountSid = "obfuscated";
const string authToken = "obfuscated";
private static string fromUser = "DirectLineSampleClientUser";
private string SMSreply = "";
public async Task<TwiMLResult> Index(SmsRequest incomingMessage)
{
// Obtain a token using the Direct Line secret
var tokenResponse = await new DirectLineClient(directLineSecret).Tokens.GenerateTokenForNewConversationAsync();
// Use token to create conversation
var directLineClient = new DirectLineClient(tokenResponse.Token);
var conversation = await directLineClient.Conversations.StartConversationAsync();
using (var webSocketClient = new WebSocket(conversation.StreamUrl))
{
webSocketClient.OnMessage += WebSocketClient_OnMessage;
// You have to specify TLS version to 1.2 or connection will be failed in handshake.
webSocketClient.SslConfiguration.EnabledSslProtocols = System.Security.Authentication.SslProtocols.Tls12;
webSocketClient.Connect();
while (true)
{
string input = incomingMessage.Body;
if (!string.IsNullOrEmpty(input))
{
if (input.ToLower() == "exit")
{
break;
}
else
{
if (input.Length > 0)
{
Activity userMessage = new Activity
{
From = new ChannelAccount(fromUser),
Text = input,
Type = ActivityTypes.Message
};
await directLineClient.Conversations.PostActivityAsync(conversation.ConversationId, userMessage);
//break;
if (!string.IsNullOrEmpty(SMSreply))
{
var messagingResponse = new MessagingResponse();
var message = messagingResponse.AddChild("Message");
message.AddText(SMSreply); //send text
SMSreply = string.Empty;
return TwiML(messagingResponse);
}
}
}
}
}
}
return null;
}
private void WebSocketClient_OnMessage(object sender, MessageEventArgs e)
{
// Occasionally, the Direct Line service sends an empty message as a liveness ping. Ignore these messages.
if (!string.IsNullOrWhiteSpace(e.Data))
{
var activitySet = JsonConvert.DeserializeObject<ActivitySet>(e.Data);
var activities = from x in activitySet.Activities
where x.From.Id == botId
select x;
foreach (Activity activity in activities)
{
if (!string.IsNullOrEmpty(activity.Text))
{
SMSreply = activity.Text;
}
}
}
}
}
The issue was actually I wasn't saving and retrieving conversationID.
For the moment I am testing using a static variable to store the value.
Then I reconnect to the conversation with it and the conversation with the bot keeps in context.
I am using the Firebase .net Admin SDK on my back end to send push notifications.
According to this link I should be able to add the following json into a message object that will open the set link when the notification is clicked on while the app is in background.
"webpush": {
"fcm_options": {
"link": "https://dummypage.com"
}
I have read through the .net Admin Sdk documentation but cannot figure out where to add this.
Here is the code that I used to new up the message object
var fcm = FirebaseAdmin.Messaging.FirebaseMessaging.DefaultInstance;
var Message = new Message()
{
Notification = new Notification
{
Title = title,
Body = message,
},
Token = user.PushTokenWeb,
};
var result = await fcm.SendAsync(Message);
Does anyone know where I would set the callback link?
In FirebaseAdmin .net v1.9.0 you can
var message = new Message()
{
Token = token,
Notification = new Notification()
{
Body = notificationBody,
Title = title
},
Android = new AndroidConfig()
{
Priority = Priority.High
},
Webpush = new WebpushConfig()
{
FcmOptions = new WebpushFcmOptions()
{
Link= "https://www.davnec.eu/aurora-boreale/previsioni/"
}
}
};
.NET SDK does not support this setting yet. It's only exposed in Node.js and Go at the moment. You can provide a pull request at https://github.com/firebase/firebase-admin-dotnet to implement this feature.
I am developing wcf push notification service using google's GCM API. i created a service which sends to all the device which use my application but, i wanted to be specific to some device. i am thinking i have to use the token i get when i register for the GCM service. but i dont know where and how to implment it. most of the online posts are in PHP and i am kind of confused when i see the codes. Any one with C# implmentation advice or in general may be?
here is my code for all the devices:
public bool notify(string sender, string message)
{
var jGcmData = new JObject();
var jData = new JObject();
bool Value;
jData.Add("message", message);
jData.Add("name", sender);
jGcmData.Add("to", "/topics/global");
jGcmData.Add("data", jData);
var url = new Uri("https://gcm-http.googleapis.com/gcm/send");
try
{
using (var client = new HttpClient())
{
client.DefaultRequestHeaders.Accept.Add(
new MediaTypeWithQualityHeaderValue("application/json"));
client.DefaultRequestHeaders.TryAddWithoutValidation(
"Authorization", "key=" + API_KEY);
Task.WaitAll(client.PostAsync(url,
new StringContent(jGcmData.ToString(), Encoding.Default, "application/json"))
.ContinueWith(response =>
{
Console.WriteLine(response);
Console.WriteLine("Message sent: check the client device notification tray.");
}));
}
Value = true;
}
catch (Exception e)
{
Console.WriteLine("Unable to send GCM message:");
Console.Error.WriteLine(e.StackTrace);
Value = false;
}
return Value;
}
thanks in advance!
1st of all I think you should not reinvent the wheel and include a Push messaging library to do all the redundant work.
I use PushSharp
Then everything is cake.
Declare the following handler class
Using the SendGCMNotification method just throw an object to serialize and a specific user's push messaging id .
public class PushNotificationHandler : IDisposable
{
private static readonly string googleApiKey;
private static PushBroker pushBrokerInstance;
static PushNotificationHandler()
{
googleApiKey = ConfigurationManager.AppSettings["GoogleAPIKey"].ToString();
pushBrokerInstance = new PushBroker();
pushBrokerInstance.RegisterGcmService(new GcmPushChannelSettings(googleApiKey));
}
public static void SendGCMNotification(Notification messageObj, String CloudMessagingId)
{
String Content = Newtonsoft.Json.JsonConvert.SerializeObject(messageObj);
pushBrokerInstance.QueueNotification(new GcmNotification().ForDeviceRegistrationId(CloudMessagingId).WithJson(Content));
}
}