I need to update my SQLite database with details sent via an online MVC application which sends a firebase data message to the Xamarin Application linked to the specific user's profile
While the app is in the foreground I can update the database directly with the details contained within the firebase data message.
The problem is that I need the database to be updated whilst the application is in a closed state so when they open it the UI and data states are already built and ready for the user (Without having to then do an HTTP request to get any new information)
Through my workings, I have seen that I must use a Firebase.Jobdispatcher...however I see that it seems to have been deprecated.
public override void OnMessageReceived(RemoteMessage message)
{
base.OnMessageReceived(message);
//Custom message received
if (IsApplicationInTheBackground())
{
//The send notification sends the push notification no problem
SendNotification(message.GetNotification().Body, message.Data);
//I wish to add specific code to write to the SQLite here
} else
{
//Notify within the application using snackbar
var mA = new MessageAndroid();
mA.ShortAlert(message.GetNotification().Body);
var uti = new FindMyDriver(); //Location pin pointing request
uti.ReturnLocationAsync(message.GetNotification().Body);
}
}
In the block where it states "I wish to add specific code .." I would like to save specific details about the loads that have been sent from the MVC application to the linked user App on a registered phone.
I would like to call a specific void to run whilst the App is offline/background.
Is this at all possible with all the controls on services etc lately?
The big issue above was that the FCM didn't actually fire the OnMessageReceived event.
This was due to the FCM being received as a notification and not as a data payload. Once I changed the payload to data it worked 100% allowing me to initialize a foreground service and run from there.
Related
I'm working on a CRM application and my client wants to download some information within last 6 months. At the moment I have created an API endpoint which returns FileContentResult object and that will open a new tab in browser and automatically download an Excel file.
But this process is time consuming (since it has over 500K data) and users don't wait in the same page until the process is done. So, once an user change between pages I get issues and sometimes the application return timeout error since the API response is slow.
Now, I'm planning to enhance that same function/API endpoint by introducing some silent job. Which means once user click on "Download" button, process will start and it will send a message stating that "Your download process has been started. You will receive an email with the report within next 15minutes". In this way, users don't have to wait and they can do something else in the system.
Currently, I'm using async task and awaits until the job is done.
public async Task<FileContentResult> ExportData()
{
//...
//... process data and create excel file
//...
//...
return new FileContentResult(*some byte array*, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")
{
FileDownloadName = $"Data.xlsx"
};
}
and I'm calling this method by
await exportService.ExportData();
My concern is what are the things I should change here in order to avoid any impact on other processes and run this as a background job. Once I get the result, I will send an email with an attachment.
Please help me with your valuable ideas. Thanks in advance
what are the things I should change here in order to avoid any impact on other processes and run this as a background job. Once I get the result, I will send an email with an attachment.
You should use a basic distributed architecture, as I describe on my blog. Specifically:
Instead of creating the report in your ASP.NET app, your ASP.NET app should just create a message indicating that the report should be created, and place that message into a durable queue.
Have a separate, independent process read the messages from that queue, generate the report, and send the email.
We have a Teams bot that posts messages in MS Teams. The first activity of a new conversation is always an adaptive card and once in a while, we update that with a new card. This worked OK until I made a new Team with this bot.
The update we are trying with UpdateActivityAsync, return NotFound.
After some troubleshooting, I noticed the following:
The new team has a different name: 19:...#thread.tacv2 as opposed to 19:...#thread.skype.
When I use an older team, it works as expected.
When I update the activity with text only (so no adaptive card as attachment) it will always update as expected.
After an update with a text, we are able to update with an adaptive card ONCE. After one update with an adaptive card, any subsequent updates with adaptive cards will return NotFound.
So, as a workaround, I now first update with text and immediately after that I send the update with the card. Which is a bad UI thing (flickering) but it works for now.
We use the old bot framework version 3, which I know is not maintained anymore, but as far as I can find, it should still work (no plans to discontinue operation). Also given the above points (specifically point 4) I would expect it uses the same calls under the hood.
So, this works for older teams, but not for a team with #thread.tacv2
await connector.Conversations.UpdateActivityAsync(
teamsConversationId,
activityId,
(Activity)messageWithCard);
And for teams with #thread.tacv2 we now have to use this
var messageWithText = Activity.CreateMessageActivity();
messageWithText.ChannelId = teamsConversationId;
messageWithText.Id = activityId;
messageWithText.Type = ActivityTypes.Message;
messageWithText.Text = "Updated";
await connector.Conversations.UpdateActivityAsync(
teamsConversationId,
activityId,
(Activity)messageWithText);
await connector.Conversations.UpdateActivityAsync(
teamsConversationId,
activityId,
(Activity)messageWithCard);
The exception does not provide too many details:
Operation returned an invalid status code 'NotFound'
Conversation not found.
Does anyone know how to avoid this change between teams and allow updates of activity with cards?
Also (and this is much less important, but I think it's useful to add) I noticed that sometimes (I've seen it twice now) Teams seems unable to render the adaptive card and displays URIObject XML instead, containing error: cards.unsupported. However, if I exit the client and restart it, it renders fine... I have never seen this so far in the old channels.
Teams client version 1.3.00.362 (64-bit) (no dev mode).
Normal Azure tenant (no preview/trial)
EDIT 11/05/2020 It seems that this also happens on teams with the 'old' name (#thread.skype). So the '#thread.tacv2' seems unrelated.
We weren't able to find logs at the exact timestamps that you provided, but did find logs for the conversation ids on those dates and see 404s with the same minute and seconds in UTC. We assume the time stamps that were provided are represented in a different timezone.
From the logs we are seeing the following pattern:
Bot sends PUT activity with card - 404 returned
Bot sends PUT activity with text - 200 returned
Bot sends PUT activity with card - 200 returned
This looks like the same pattern that you shared in your original post.
There is a scenario that's causing 404s to be returned on PUTS whenever the bot tries to update an existing card message with the exact same card after new messages have been sent to a reply chain
These are the repo steps:
Bot send card to reply chain (can be root message or reply message)
Any user sends a message to the chain
Bot attempts to update message with the exact same card
Is it possible that your bot is encountering this? Is there a way to check whether the card your bot is sending in the first PUT request is the same card that is already in the original message
I tried adding custom telemetry per the docs (https://learn.microsoft.com/en-us/azure/bot-service/bot-builder-telemetry?view=azure-bot-service-4.0).
I am missing something because I cannot find my custom event in the App Insights logs.
I tried interacting with the bot and searching the App Insights logs for "VeryImportantProperty" and "VeryImportantValue"
I wrote this class:
public class TelemetryMiddleware : TelemetryLoggerMiddleware
{
public TelemetryMiddleware(IBotTelemetryClient telemetryClient, bool logPersonalInformation)
: base(telemetryClient, logPersonalInformation)
{
}
protected override async Task OnReceiveActivityAsync(Activity activity, CancellationToken cancellation)
{
Dictionary<string, string> propertyItems = new Dictionary<string, string>
{
{"VeryImportantProperty", "VeryImportantValue" }
};
var properties = await FillReceiveEventPropertiesAsync(activity, propertyItems);
TelemetryClient.TrackEvent(TelemetryLoggerConstants.BotMsgReceiveEvent, properties);
}
}
I added it in startup.cs as a service available for injection:
services.AddSingleton<IMiddleware, TelemetryMiddleware>();
I also added all the other items named in the article required as injectable services.
I deployed the bot and interacted with it, but I cannot find my VeryImportantValue or property even after a full search of my App Insights logs.
I’m sure I am missing something, but from the docs, I cannot determine what it is.
Any ideas or pointers in the right direction?
You should be able to see these events by going to Azure Portal > All Resources > Application Insights Resource > Overview page > Logs (Analytics) which is along the top, above the details for the Application Insights resource.
Then if you enter the following for your query:
customEvents
| where name == "BotMessageReceived"
and click run (you may have to select the query text you entered before clicking run.
Your VeryImportantProperty data should show under the customDimensions column.
The getting started information is available here.
Edit
If you still cannot see the log entries then you will need to debug where the issue is. The steps I would recommend are:
Get the latest version of the Bot Framework Emulator.
Update your TelemetryMiddleware class to have a the following field private IBotTelemetryClient _telemetryClient;
Update your TelemetryMiddleware constructor to assign the value from the telemetryClient parameter to your new _telemetryClient field.
Update the call inside OnReceiveActivityAsync to use the new _telemetryClient field instead of the TelemetryClient class (you are calling TrackEvent statically currently which isn't what you want.
Run your bot locally using the Bot Framework Emulator.
Add a breakpoint on the line where you call TrackEvent
Create the scenario which should trigger OnReceiveActivityAsync (send a message to the bot).
Use F10 to step over the TrackEvent line and ensure that it is called successfully.
At this stage I would also inspect your variables to ensure they have the values that you expect.
Wait for the event to flow through to App Insights (might take up to 5 minutes).
If this still does not work I would create a new Application Insights API key and updating the following places with the new value:
For local testing:
Your appsettings.json file so that you can test locally.
For production:
The Application Insights Instrumentation key under the Settings tab of your Web App Bot in Azure.
Also check that the value for Application Insights Application Id under the Settings tab of your Web App Bot in Azure matches the Application Id value under the API Access tab of your Application Insights resource.
Follow the steps above to test locally using the emulator.
Once the logs are flowing through locally use the Test in Web Chat functionality to ensure that it is working in production.
This question already has answers here:
How to monitor SQL Server table changes by using c#?
(11 answers)
Closed 6 years ago.
I want to get notified when a certain change occurs in Database table. Consider the case: I want to perform a certain action when the column in a row changes its value to 5. How can I achieve it. I am using C# and entity framework to access the database.
For this you have to make a schedule job which will continuously(like interval of 5 minutes) ping database and notify you as like Facebook's notification bar.
Also you can write trigger on that table which will insert/update notification table and from there you will get notify.
The short answer is that you should probably try and manage this outside of SQL server. I have to assume that you have some application logic executing outside of SQL server that is the source of the update. Ideally your notification logic should be placed in your application tier before or after the database is updated.
Should you not be able to achieve this, three other options I can offer are:
polling You build a service that reads the value from SQL server in a loop. The loop should read the value periodically, and perform the notification. Most engineers avoid polling as from a best practices standpoint it is typically contra indicated due to adding persistent load to the database. Although polling should be avoided, it's surprisingly common in the field.
msmq You update the value via a stored procedure, and use this article to send a message to MSMQ when the value is 5. You will need to write a service to consume the MSMQ message and process the notification. You may use a WCF service using MSMQ transport to make this easy.
email You send an email using sp_send_dbmail in the update stored procedure, and build the necessary notification consumer(s). It should be noted that this method will likely also involve polling if you consume the email electronically. You can avoid that by using IMAP IDLE to process the email notifications. Try MailKit
Reporting services also apparently offers notifications, but I am not familiar with them.
using(var context = new FooEntities)
{
try
{
var customer = context.Customers.First(i=> i.CustomerID = 23);
customer.Name = "Bar";
context.SaveChanges();
//Write your notification code here
}
catch(Exception ex)
{
//Write notification along with the error you want to display.
}
}
Search in google there's many different way of displaying a notification.
I am using Windows azure push notifications. Every time a new notification is received a Toast is displayed with the information received, is there anyway I can disable this feature programmatically? The reason I want this is because I am trying to develop a FPS game and I am using the Push notifications to update locations, for obvious reasons I don't want the data received to get displayed.
You can hide the toast notification by setting the expiration time of the ToastNotification to DateTime.Now, that way it would expire as soon as it is displayed. You can do that by using the PushNotificationReceivedEventArgs args that is passed.
args.ToastNotification.ExpirationTime = DateTime.Now;
A better solution as provided by Gaurav is to use
args.Cancel=true;
What you could do is consume the PushNotificationReceived event and then handle it there. I did the same for one sample chat application I built. Look for the code for app.xaml.cs in my blog post here: http://gauravmantri.com/2012/08/30/how-i-built-an-awesome-chat-application-for-windows-8-with-windows-azure-mobile-service/.