Not getting the "MESSAGE_DELIVERED" Firebase event - android

I am trying to measure the latency between having a message exit Firebase Servers and being received on an Android app via the Firebase SDK. I have BigQuery integrated with my Firebase project, and have tried adding the following code:
// In the manifest:
<meta-data android:name= "delivery_metrics_exported_to_big_query_enabled"
android:value="true"/>
// In my Application object:
FirebaseMessaging.getInstance().setDeliveryMetricsExportToBigQuery(true);
The code seems to be exporting data to BigQuery. However, to calculate what I want I need timestamps for two different types of events associated to the same message id, "MESSAGE_ACCEPTED" and "MESSAGE_DELIVERED". Then, all I have to do is run a simple query that calculates the timestamp difference between those two.
My problem is: I can never seem to get the "MESSAGE_DELIVERED" variant for a given message id. I only ever get the "MESSAGE_ACCEPTED" side of the equation.
I am sending messages to the Android device via my own JavaScript app, and the request I make is like so:
app.get('/triggerAnt', function(req, res){
axios.post('https://fcm.googleapis.com/fcm/send', {
to:<TOKEN_FOR_DEVICE_GOES_HERE>,
notification:{
"title":"TESTNOTIFICATIONLATENCY",
"body":"TESTINGLATENCY"
},
fcm_options: {
analytics_label:<LABEL_HERE>
}
}, {headers: headers})
.then((response) => {
console.log(response.status);
}, (error) => {
console.log(error);
});
})
I would like to point out that the notification does effectively reach the device and I can open it too.
Is this delay on BigQuery's side or am I doing something wrong?
Thank you.

Related

React-Native Firebase: Token refresh not working

I have an issue with react-native-firebase (or firebase) in which my app does not receive a trigger after the auth token refreshes. It's pretty much the same issue as [1], but they never posted a solution.
So, what happens is that both on an Android phone and on the Android emulator (no idea about iOS), signing up, logging in and logging out works perfectly, meaning the listeners correctly see when I do a logout() etc. But the listeners never fire when the token refreshes.
My first question is: Am I correct to assume that the onIdTokenChanged-listener should automatically fire after 60 minutes without having to do anything else, e.g. call any firebase function, such that the app just sits there doing nothing for 60 minutes and then receiving the event and replacing the token?
My main component which contains the listeners looks like this:
class ReduxAppWrapper extends Component {
componentDidMount() {
firebase.auth().onAuthStateChanged((user) => {
console.log('COMP DID MOUNT: AUTH STATE CHANGED! ' + JSON.stringify(user));
});
firebase.auth().onIdTokenChanged((user) => {
console.log('COMP DID MOUNT: TOKEN CHANGED! ' + JSON.stringify(user));
});
firebase.auth().onUserChanged((user) => {
console.log('COMP DID MOUNT: USER CHANGED! ' + JSON.stringify(user));
});
};
render() {
return (
<ReduxProvider store={store}>
<MenuProvider>
<PaperProvider>
<AppContainer />
</PaperProvider>
</MenuProvider>
</ReduxProvider>);
}
}
Normally inside the listener I have a function that dispatches a redux-action such that the authentication information is broadcast across my components. Inside those components I use the jwt token for http-requests to my backend.
Now the backend of course uses firebase to validate that token (and this is where the problem occurs after the 60 minutes since it retrieves an outdated jwt), but I think I am right to assume that the problem lies within the app since the refresh does not happen.
I'd be really glad if someone could point me to where to look, I also tried to find out in the firebase console whether a token refresh event was sent, but I could not find anything about that.
So basically:
1) Am I right to assume that the firebase.auth().onIdTokenChanged() function should be called without me doing anything else? Or is it not enough to define the listener once in the main component (also regarding the fact that other screens will be rendered on top of that due to the stack-nvigation).
2) If the code is fine, do you have any hints for where to look?
Thanks so much!
[1] https://github.com/invertase/react-native-firebase/issues/531
For anyone with the same issue, I ended up asking firebase asking for the token everytime I needed it. I still think this should not be necessary but I did not want to spend any more time analyzing why the refresh did not work automatically. So what I am doing in the app is
firebase.auth().currentUser.getIdToken().then((token) => {
fetch(url, {
method: 'GET',
headers: { Authorization: token }
})
}
¯\_(ツ)_/¯
Apparently, with getIdToken, Firebase only makes a call to its server to get a new token if the current token has expired; it does not create unnecessary requests if it does not have to.
Quite a crucial detail which can be confusing if you are not aware of it and makes you (rightfully) assume that onIdTokenChanged is a listener which you would need to use to automatically update the token ...
https://firebase.google.com/docs/reference/js/firebase.User.html#getidtoken
Returns the current token if it has not expired. Otherwise, this will refresh the token and return a new one.

Endless loop in dialogflow v2 detectIntent after having split one input query in two queries

Per default, Dialogflow can only match one intent per one one input:
e.g
User asks: "How are you?"
Dialogflow Agent responds: "I am feeling good!"
(Matched intent: intents.howareyou)
But as soon as the user asks two questions in one input, the agent can not match multiple intents. Only one intent is matched with a smaller confidence interval)
e.g
User asks: "How are you? Do we want to go shopping?"
Dialogflow Agent responds: "Yes, lets go shopping!"
(Matched intent: intents.shopping)
There are two options now to enable the agent to answer both questions in one input:
Create an intent and let the agent response exactly for these two questions.
=> This is a very bad solution, as soon as you add more possible questions/intents. Then you would need to create every combination of every question.
Split the one input into several queries and let the agent perform the intent matching again on the splitted query.
=> This is the preferred way
Based on some blogs in the internet (e.g. https://docs.meya.ai/docs/handle-multiple-intents-in) the second option is what I did.
The Default Fallback Intent is set to use the Fulfillment webhook and this a small part of code executed:
function parseMultipleIntents (agent) {
const query = agent.query;
var pattern= /(.+?[!.?]+)/gm;
var match = pattern.exec(query);
while (match !== null) {
console.log(match[0]);
handleQuery(match[0]); //<----
match = pattern.exec(query);
}
}
The handleQuery method is the actual method, where the splitted queries are handled:
function handleQuery(query){
console.log(query);
// The path to identify the agent that owns the created intent.
const sessionPath = sessionClient.sessionPath("PROJECT_ID", "FIXED_SESSION_ID");
const request = {
session: sessionPath,
queryInput: {
text: {
text: query,
languageCode: 'de',
},
},
};
sessionClient
.detectIntent(request)
.then(responses => {
console.log('Detected intent');
const result = responses[0].queryResult;
console.log(` Query: ${result.queryText}`);
console.log(` Response: ${result.fulfillmentText}`);
if (result.intent) {
console.log(` Intent: ${result.intent.displayName}`);
} else {
console.log(` No intent matched.`);
}
})
.catch(err => {
console.error('ERROR:', err);
});
}
The problem:
If I comment everything in the handleQuery method except console.log(query); then the console outpuut in the firebase console looks fine:
originalQuery: und?warum?
11:39:58.240 PM dialogflowFirebaseFulfillment warum?
11:39:58.238 PM dialogflowFirebaseFulfillment und?
But as soon as I uncomment the rest of the handleQuery and the code looks like above, I get the following console messages which is not stopping. The messages go one if I scoll up in the console. It seems like some kind of loop:
-
-
Do I use detectIntent correctly or do you had such experiences? Or can you spot an issue?
I presumed issues with sync/async calls and also added Promises, but the same happened...
Thanks

Twilio voice call answering and talking

I have implemented android twilio call with this tutorial,
https://github.com/twilio/voice-quickstart-android
Everything works perfectly as they have mentioned. The call rings I can attend the call and listen to the VoiceResponse message I saved in server. My requirement is I need to talk to the one android twilio application to other android with same twilio application instead of receiving VoiceResponse message. If I make phone calls to actual phone numbers then I can talk and listen without any problem, but from application to application speaking does not work.
I am using node js as server code, the first calling person code is given below.
client.api.calls.create({
url: url,
to: phoneNumber,
from: callerId,
}, function(err, call) {
if (err) { console.error('There was a problem starting the call: ', err); }
console.log('Call with sid: ${call.sid} was started');
});
xml response for url is
router.post('/callSecond', function(request, response) {
const voiceResponse = new VoiceResponse();
const dial = voiceResponse.dial({ callerId: 'client:al' });
voiceResponse.say("Congratulations! You have received your first inbound call! Good bye. Welcome to Twilio! Welcome to Twilio!!!! Welcome to Twilio");
dial.client("leo");
console.log('Response :' + voiceResponse.toString());
response.send(voiceResponse.toString());
});
Can anyone please help me to find a solution for this, speaking to each other using twilio mobile application.
Thank you in advance

cordova google plus plugin not getting full detail except email?

I am using Cordova plugin to login with Google Plus on Android not receiving User data except email.
The success callback (second argument) only provinding email object.
function (obj) {
alert(JSON.stringify(obj)); // Only show email
},
It is not provideing following contents:-
obj.userId
obj.displayName
obj.imageUrl
obj.idToken
obj.oauthToken
obj.gender
obj.givenName
obj.middleName
obj.familyName
obj.birthday
obj.ageRangeMin
obj.ageRangeMax
I have read many articles but couldn't find out how it will show full detail.
I have also tried with scopes parameter.
{
'scopes': 'profile, email',
'offline': true,
},

Ionic push not working - user not registered

I just had my first contacts with the ionic framework. I've worked with Phonegap and AngularJS before however, so it was not all that new to me.
I found out that there is this new feature to use Google Cloud Messaging push notifications in Ionic, through the Ionic Push feature (http://blog.ionic.io/announcing-ionic-push-alpha/).
Related lines of code from app.js
angular.module('starter', ['ionic','ionic.service.core', 'starter.controllers', 'starter.services'])
.run(function($ionicPlatform) {
$ionicPlatform.ready(function() {
// Hide the accessory bar by default (remove this to show the accessory bar above the keyboard
// for form inputs)
if (window.cordova && window.cordova.plugins && window.cordova.plugins.Keyboard) {
cordova.plugins.Keyboard.hideKeyboardAccessoryBar(true);
cordova.plugins.Keyboard.disableScroll(true);
}
if (window.StatusBar) {
// org.apache.cordova.statusbar required
StatusBar.styleLightContent();
}
// enable push notifications
Ionic.io();
// enable users (http://docs.ionic.io/docs/user-quick-start)
// this will give you a fresh user or the previously saved 'current user'
var user = Ionic.User.current();
// if the user doesn't have an id, you'll need to give it one.
if (!user.id) {
user.id = Ionic.User.anonymousId();
// user.id = 'your-custom-user-id';
}
console.log('user-id:' + user.id);
//persist the user
user.save();
var push = new Ionic.Push({
"debug": true,
"onNotification": function(notification) {
var payload = notification.payload;
console.log(notification, payload);
},
"onRegister": function(data) {
console.log(data.token);
}
});
push.register(function(token) {
console.log("Device token:",token.token);
});
push.addTokenToUser(user);
console.log('token added to user');
});
})
Log from ionic serve
ionic $ 0 361081 log Ionic Core:, init
1 361083 log Ionic Core:, searching for cordova.js
2 361085 log Ionic Core:, attempting to mock plugins
3 361155 log user-id:1cc3d21c-b687-4988-b944-ad07b1a677c8
4 361158 log Ionic Push:, a token must be registered before you can add it to a user.
5 361159 log Ionic Push:, token is not a valid Android or iOS registration id. Cannot save to user.
6 361159 log token added to user
7 361160 log Ionic Push:, register
8 361160 error ReferenceError: PushNotification is not defined, http://localhost:8100/lib/ionic-platform-web-client/dist/ionic.io.bundle.min.js, Line: 2
9 361526 log Ionic User:, saved user
Any input is welcome, I am also more than happy to provide more information if needed.
EDIT 10/05/2015:
found out that dev_push = false only works on physical devices, not in browser
I tried to add token to user before even registering the user
I'm having the same problem, seems not many answers online at the moment.
but even on real device, it won't save the token to user.
I just had to decide go live without push first, then use ionic deploy to follow up.
also I think you have to put this line
push.addTokenToUser(user);
inside the register callback according to this doc
http://docs.ionic.io/docs/push-usage
You also need to declare 'ionic.service.push' as a dependency in your angular module if you'd like to use it.
angular.module('starter', ['ionic','ionic.service.core', 'ionic.service.push'])
I have it like this and it works:
Ionic.io();
var user = Ionic.User.current();
if (!user.id) {
user.id = Ionic.User.anonymousId();
// save our newly created user
user.save();
}
var push = new Ionic.Push({});
push.register(function (token) {
console.log("Got Token:", token.token);
// now we have token, so add it to user
push.addTokenToUser(user);
// don't forget to save user to Ionic Platform with our new token
user.save();
});
// set this user as current, so we can acess him later
Ionic.User.current(user);
Did you use this
ionic config set dev_push true-if testing in emulator or laptop
ionic config set dev_pushfalse - if testing on the phone
ionic push --google-api-key Your API Key
ionic config set gcm_key Project Number
Your token is the registration id that is unique for a particular device. That is sent to you by android.
Your Phone (With the API Key)---------> to Google's GCM
Google GCM (recognises it's you via your Project number and API key) -----> Oh it's you let me make a note of it. (Save a token id in it's DB and send's one to you.)
You get a registration id unique for your device(will change if an app is uninstalled).
You call your server say hey it's me your user. Please Notify me if you get something.
Server obliges, says, okay dude, I got this. Saves the registration id with your details probably your username in it's DB.
Now from Server.
I need to inform my users about a great deal(or an accident or something).
Pull up all targeted registration Id's from DB(maybe on some condition)
registrationIds.push(regId) //in a loop
and sender.send(message, registration, function(err, result){
});
Send to Google. Google see's oh only these many people(not all maybe) from this API Key need a notification. no Problem I will notify them and you receive a notification, my dear friend.
As mentioned in the link , Adding token to the $ionicUser is done by doing , user.addPushToken(pushToken); .
For this to work you should first configure the app not to use developement pushes by ,
ionic config set dev_push true
After initialising Ionic.io and Ionic.push , load the user or create one with a new random id ,
Ionic.io();
var push = new Ionic.Push();
Ionic.User.load(localStorage.id).then(function (user) {
Ionic.User.current(user);
pushFactory.register(push, user);
}, function (error) {
/*the user with that id is not present , so create one with a random id and register the push */
});
The push factory is defined as below,
function pushFactory() {
return {
'register': function (push, user) {
push.register(function (pushToken) {
user.addPushToken(pushToken);
user.save().then(function (answer) {
console.log('user saved'+answer);
})
})
}
}
}

Categories

Resources