How do I detect when my app crashes and send a firebase event at that time? - crashlytics

So I intend to detect and trigger a firebase custom event when my app crashes, is there a recommended way to check that? I tried AppDelegate method applicationWillTerminate but it didn't work, similarly I tried to observe through an NSSetUncaughtExceptionHandler but again in vain. I want to know how Crashlytics or Sentry or Bugsnag do it. Any help will be more than helpful.

Whenever app is crashed it means it doesnt respond to any of the events triggered or any calls you make in your app. So if it helps you can send event parameters in the Crash log event something like this.
let keysAndValues = [
"string key" : "string value",
"string key 2" : "string value 2",
"boolean key" : true,
"boolean key 2" : false,
"float key" : 1.01,
"float key 2" : 2.02
] as [String : Any]
Crashlytics.crashlytics().setCustomKeysAndValues(keysAndValues)
Refer : https://firebase.google.com/docs/crashlytics/customize-crash-reports for more details

Related

Question about usage of express-validator with nested object

I am trying to verify whether the title of the board is not empty. If my request is sent in the format of {title: ""} I am able to do check("title").not().isEmpty(), and it works just fine.
However, if I am sending the request like this:
board: {
"title": "Something
}
Then the check from the above doesn't work as I am always getting the title to be undefined. How can I test for the title being not empty in this case using express-validator?
Thank you!
Figured it out. It should be check("board.title").not().isEmpty()

Issue in odoo 8 displaying warning message

I am trying to validate a "capacity" field with onchange decorator but for some reason when I send the warning message the previous line stops working. The template updates the field fine whitout the warning
#api.onchange('capacity')
def check_capacity_values(self):
if self.capacity<0:
self.capacity=0
raise Warning(_('wrong capacity.'))
You can use a dictionary as return value for methods decorated by api.onchange. The key for warning messages will be warning and the value another dictionary with keys title and message. An example:
return {
'warning': {'title': "WARNING!",
'message': "It isn't allowed to have a negative capacity!"}
}
I think that the problem may be that the change you made in self.capacity just before raising the warning is not stored in the database because you are using #api.onchange, so the new value is just shown in the UI, but not stored in the database.
Try it using #api.depends instead, the change will be reflected both in the UI and the database.
#api.onchange('capacity')
def check_capacity_values(self):
if self.capacity<0:
self.capacity=0
return {'warning': {
'title': "Warning",
'message': "message",
}
}

Setting title for multiple instances of a parameterised route page

I define a route config as:
{ route: 'page/:id', name: 'page', moduleId: 'page', title: "Page #" }
I've also got another component listening to the router:navigation:complete event (EventAggregator), and, when a different fragment is spotted, it adds it to an array and displays this on the screen (as a sort of History list) using NavigationInstruction.config.navModel.title
When I navigate to the 'page' component with different ids time, e.g. #/page/1, #/page/2, #/page/3. I call NavigationInstruction.config.navModel.setTitle("Page " + id) from the activate() method.
In my history, I initially will see:
"Page 1"`
... then when navigating to #/page/2...
"Page 2"
"Page 2"
... then when navigating to #/page/3...
"Page 3"
"Page 3"
"Page 3"
Because the RouteConfig is shared between the different NavigationInstructions, changing the navModel.title value affects ALL NavigationInstructions derived from that RouteConfig.
Anyone got any ideas how I can set a custom title for each instance of the Page component? Is Aurelia expected to deal ok with multiple simultaneous instances of the same component?
I've considered using the new router.transformTitle hook, but as I'm likely to eventually include more information in the title, e.g. "Page 1: Contents", "Page 2: The First Chapter", that feels sub-optimal and likely to leave me doing a lot of rolling-my-own architecture to dynamically resolve the string.
I created a very simple app to test this. I did use a slightly different strategy though. I used the activate callback on the page viewmodel instead of subscribing to the router:navigation:complete event.
Here's my code:
export class Page {
activate(params, route, instruction) {
this.pageNumber = parseInt( params.id || '1' );
instruction.config.navModel.setTitle("Page " + this.pageNumber)
}
}
I'm not seeing the behavior you are seeing:
What version of the framework module are you working with?
From looking at the code, and responses (thanks #Ashley Grant), it appears that my expectations of NavigationInstruction were not accurate.
A NavigationInstruction represents a single workflow of triggering, navigation, deactivating previous pages, and activating new pages, and firing any events triggered as part of that process.
It does not - as I'd thought - represent a 'instance' of a RouteConfig (i.e. the fragment, plus params). Therefore, referring to a NavigationInstruction after the navigation:router:complete event has fired is not intended, therefore doesn't work!
I'll now rewrite my code to take a copy of the title when the navigation:router:complete event fires (this is actually non-trivial, requires calling the _buildTitle() private method on the instruction) - and have a raised a FR - https://github.com/aurelia/router/issues/469 - to request that this operation be made less opaque.

Wit.ai chooses wrong branch in conversation flow

I have a flow based conversation modelled in wit.ai. After executing a custom action and sending the results to the user, the user should have the possibility to:
say something like 'show me more' or
say something like 'thank you' in which case the flow is configured to return a direct message 'you are welcome'
I used two separate intents 'more' and 'thank you' to differentiate between the branches. When I send 'show me more' to the bot, wit.ai correctly recognizes the intent 'more'. However, the conversation then takes the wrong branch and the bot sends 'you are welcome' as shown in this wit.ai response body:
{
"confidence" : 1,
"type" : "msg",
"msg" : "You are welcome!",
"entities" : {
"intent" : [ {
"confidence" : 0.9707855789235582,
"type" : "value",
"value" : "more"
} ]
}
}
Why is this happening?
Well even I have faced similar issue sometimes but I was able to get it working by setting the right context or entity field names for "has" & "does not have" options for respective actions and responses in the Actions tab. This seems to have worked although it is a bit frustrating to see that Wit does not recognise the flow based on intent sometimes.

Telegram bot: How do I send message with inline keyboard and hide custom keyboard simultaneously?

Step 1: Send user a message with ReplyKeyboardMarkup with few buttons (for example ["Yes", "No"])
Step 2: If user click one of the buttons (for example "Yes") I want to display a message with inline keyboard and hide the buttons sent at step 1.
Is it possible to do? The message has just single reply_markup property and can be either InlinkeKeyboardMarkup or ReplyKeyboardHide. The only way to do that I see is to send 2 messages (first to hide keyboard and 2nd with inline keyboard) but that would not be best solution from user experience point of view. I'm OK to do couple of request but want to have just 1 message visible to user.
Any thoughts?
It's impossible right now. Telegram Bot API currently allows sending only one type of keyboard: inline or simple (including KeyboardHide and other).
There isn't any logical solution. but there's a trick. you can send a message to remove the previous keyboard, then remove this message, finally send the next message with it's keyboard.
// send a fake message
Message sentMsg = bot.SendTextMessageAsync(chatID, ".", replyKeyboardMarkup: new ReplyKeyboardRemove()).Result;
// remove the fake message
bot.DeleteMessageAsync(chatID, sentMsg.MessageId);
// send the main message with it's keyboard
bot.SendTextMessageAsync(chatID, "the next message", replyKeyboardMarkup: new ReplyKeyboardMarkup(keyboardData));
I guess you want the button should disappear once it's pressed:
ReplyKeyboardMarkup MyButton = new ReplyKeyboardMarkup();
MyButton.OneTimeKeyboard = true;
You can even make it more responsive by adding this:
MyButton.ResizeKeyboard = true;
But you can send two messages, the first one would send ReplyKeyboardHide/ReplyKeyboardRemove and the second would send the inline keyboard
Just set the OneTimeKeyboard Property to true,
Button.OneTimeKeyboard = true;
Once button is used it's never showing again
you better use inlinekeyboard for both yes/no and the preceding keyboard which you want to show after pressing yes or no. that way, you can edit the yes/no inlinekeyboard message and show new keyboard.
you can send the inlineKeyboard and by checking it's callBackQuery.Data parameter you can edit the sent message again and show your new message instead.
below is a sample update message json:
{"update_id":14603298,
"callback_query":
{
"id": "479899181065761766",
"from": {
"id": 111735238,
"first_name": "eric",
"username": "...."
},
"message": {
"message_id": 22,
"from": {
"id": 3576731383,
"first_name": "the_bot_name",
"username": "mybot_bot"
},
"chat": {
"id": 111745258,
"first_name": "eric",
"username": "....",
"type": "private"
},
"date": 1492113810,
"text": "sent message"
},
"chat_instance": "5419183837652256438",
"data": "yes"
}}
so, when the user clicks on yes or no, you will get an update message. based on above update message, the chatid and messageid are known so using the c# Telegram.Bot library the edit code is like:
var chatid= 111745258;
var messageid=22;
TelegramBotClient api = new TelegramBotClient("YOUR_TOKEN");
var new_keyboard = new InlineKeyboardMarkup(
new[]
{
new[]
{
new InlineKeyboardButton("step_1","step1") ,
},
new[]
{
new InlineKeyboardButton("step_2","step2"),
new InlineKeyboardButton("step_3","step3"),
},
new[]
{
new InlineKeyboardButton("step_4","step4"),
}
});
api.EditMessageReplyMarkupAsync(chatid, messageid, replyMarkup: new_keyboard);