Android FCM token without colon (:) - android

I'm building a VoIP app, and I'd like to use FCM to be notified of incoming calls. The FCM token generated on Android contains a InstanceId prefix, followed by a colon (:). However, due to an implementation detail, I am unable to use string that contains colons. Is there a way to generate a valid token that doesn't contain a colon?
Specifically, I'm using react-native-pjsip, and the library crashes when I pass the token in the contact params, since it contains a colon. It works when I wrap the string in double-quotes (" "), but my SIP provider doesn't support parsing these strings in quotes. So I'm trying to find a way to generate a token that will keep both sides happy, which is one that doesn't contain a colon.
Any help is much appreciated!

There is no API to control what tokens get generated by Firebase Cloud Messaging. So what you'll need to do is encode the token you get into a value that is valid for your infrastructure. For example, you could use a simple URL encoding, which would turn a token a:bc into a%3Abc.

Related

FCM: Invalid registration token. Check the token format

I’m implementing Firebase Cloud Messaging (FCM) and am experiencing a problem that I’m unable to solve. I have implemented FirebaseMessagingService and FirebaseInstanceIdService according to the guide(s). When I go to Firebase Console for my app, and use the Notification function, I can successfully send a message to ALL my app instances (using the package name).
Now, in the code I have fetched the Firebase Instance Id (token) by use of the following code:
String token = FirebaseInstanceId.getInstance().getToken();
SendFirebaseTokenToServer(token);
(note that currently I’m using HTTP protocol, as my server does not yet have a cert). Anyway using the token I get from the call above, I go back to the Firebase Console and try to send a message to one (1) installed instance of my app. I grab the token from our server DB where it is stored as "varchar(max)". When I do that I get the following error message:
Invalid registration token. Check the token format.
I have googled that and found only one hit (having to do with Firebase and iOS):
http://stackoverflow.com/questions/41343520/ios-invalid-registration-token-check-the-token-format
That issue indicates that a cert was required (I think I’m reading it correctly). I’m not sure what I’m doing wrong. I need to get this to work using the Firebase Console first, then my server guy can start on his end knowing that it should work.
Turns out i was programatically encoding all POST or PUT parameters prior to sending to our server. the FCM token had a semicolon in it, which got encoded to a "%3A", seemingly causing the problem.
do NOT encode the FCM token.

Firebase Notifications - Invalid reg token, please check token format in Android

If I send push message by selecting a package from Firebase console, the push goes to all devices, but during sending to individual device, it displays the error:
Invalid reg token,please check token format
Error Snapshot:
UserID in console is not the registration token for Firebase messaging. By Firebase docs:
on initial startup of your app, the FCM SDK generates a registration token for the client app instance. If you want to target single devices or create device groups, you'll need to access this token by extending FirebaseInstanceIdService.
My last registration token looks like
cpeBAc1NkUE:APA91bEpAKHQTdgkWVdDzDZG8BPon0APaIhbbuSejDpZF-FO1gD2saDV7_EQDo2WEz0H6e5U-uf0i-v4b25NXgGzV2oUrNuboM5675WY7VCP3JcBl8BCNY7eV0VFGHT9oRox0EEoo_ch
In the other answer, you mentioned in the comments that you're Registration Token is:
cbuJIjkg9zQ%3AAPA91bHavuWCuRuWIBrDOoHUK-RsjU1yewigurrYzHe0cP‌​iTQINykKjrLf8E0qEwJj‌​3XmJ1IoTmn0r2EoLR_mA‌​HGOjlA61CnQ8aSn2WxWK‌​KByOwbsnqoVeaeWQIeGU‌​_yh4wnZ67soLtI
I noticed the % (percentage character) included in it, which isn't a usual character included in registration tokens. Figured that it was possible that this was encoded somehow. When decoded, this is the value:
cbuJIjkg9zQ:APA91bHavuWCuRuWIBrDOoHUK-RsjU1yewigurrYzHe0cP‌​iTQINykKjrLf8E0qEwJj‌​3XmJ1IoTmn0r2EoLR_mA‌​HGOjlA61CnQ8aSn2WxWK‌​KByOwbsnqoVeaeWQIeGU‌​_yh4wnZ67soLtI
Notice that the %3A was turned into : (colon). This is one of the usual characters. So I would suggest that you try the value above.
And as a reminder, the InvalidRegistration error (emphasis mine):
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.
Don't even encode it. Use it as is. Also, do note that the Registration Token should be kept secret.

Passbook / Wallet pkfile Android Auto-Update

I am currently working on a pkpass library for Android. There is one point that I cannot figure out. The Apple's PassKit Web Service Reference specifies how to register a device for automatic updates. This seems to work only with iOS devices.
However, there are a couple of apps out there for Android that are able to register for automatic updates somehow. Wallet Passes | Passbook and Pass2U Wallet for Passbook for instance.
I created a demo pkpass file using PassSource's API. When I update the file on their website, those apps get notified somehow and then show a notification to the user.
This is the behavior I'm trying to create but I cannot figure out for the life of me is what URL with which parameters to call.
I tried every possible combination of values for:
POST request to: webServiceURL/version/devices/deviceLibraryIdentifier/registrations/passTypeIdentifier/serialNumber
Parameters
webServiceURL
The URL to your web service, as specified in the pass.
version
The protocol version—currently, v1.
deviceLibraryIdentifier
A unique identifier that is used to identify and authenticate this device in future requests.
passTypeIdentifier
The pass’s type, as specified in the pass.
serialNumber
The pass’s serial number, as specified in the pass.
Header
The Authorization header is supplied; its value is the word ApplePass, followed by a space, followed by the pass’s authorization token as specified in the pass.
Payload
The POST payload is a JSON dictionary containing a single key and value:
pushToken
The push token that the server can use to send push notifications to this device.
as specified on the apple documentation.
I also studied Walletpasses Documentation and Pass2U Documentation
Help is greatly appreciated!
Thanks!

How to programmatically access the Google API key in google-services.json

The app uses Google Cloud Messaging and contains a google-services.json file which itself contains Google API authentication info, including the API key. GCM functions as expected.
The app contains a testing facility that sends a GCM message using HTTP, and it needs the API key. How do I access that key, the one stored in google-services.json? I do not want to use GoogleCloudMessaging to send the messages (I'm using OkHttp and it does the job nicely).
Hopefully it is not necessary to duplicate it in the app.
Sorry, a bit late to the game here...
The google-services.json file gets parsed and its values get added to an xml which you have access to:
https://developers.google.com/android/guides/google-services-plugin
In your case, you could get the api key with:
activity.getResources().getString(R.string.google_api_key);
You can just get the API key off your GoogleCloud platform then go to credentials and you can grab your API key off of there.
https://console.developers.google.com/
Is that what your looking for?
But if you need to access it (which is should never change unless your change the json file itself) Then you could just parse the json file with a parser. But thats adding more work than needed. I would just copy and paste it from the web.
Ok I see what you going for try using this and using the NSDefualts
Store the token like this:
if (registrationToken != nil) {
self.registrationToken = registrationToken
print("Registration Token: \(registrationToken)")
//store the registation token for use in the postData function in the login page
self.loginInformation.setObject(self.registrationToken, forKey: "GCMToken")
let userInfo = ["registrationToken": registrationToken]
And retrieve it anywhere in the project like this:
myNoteGCMID = loginInformation.objectForKey("GCMToken") as! String
Then if it changes you don't have to change it in but just one place. The change will occur everywhere you call it.

What is the proper way to validate google granted OAuth tokens in a node.js server?

I'm trying to authenticate a mobile application for the Android platform to a custom node.js server api. I would like to use Google OAuth2 tokens for this rather than roll my own authentication, since Android devices with Google Play installed make this available to app developers. I'm using the GoogleAuthUtil.getToken call from the Google Play Services library, documented here. I'm trying to follow the advice outlinedin this android developers blogpost
The getToken method is returning in my case a long 857 byte string. If I try to pass this token to Google's TokenInfo endpoint, it returns:
{'error': 'invalid_token', 'error_description': 'Invalid Value'}
What am I doing wrong here? In the 'scope' of the getToken call, I am sending:
audience:server:client_id:**i_put_my_clientid_here**. I have a clientid generated for "installed applications". Using this client id, the call to getToken doesn't work at all. When I generated a client id for a "service account", the call succeeds, but I get an 857 byte token that fails when passed to the TokenInfo endpoint as described above.
EDIT:
I also created a client id for "web applications", as it appears that is the right client id to use when calling getToken. But the behavior is the same, I get back an 857 byte token that doesn't validate when calling Google's endpoint.
How can I properly get a valid auth token using Google Play services on Android? Once I have the right token, what is the right node.js library to validate it server side? Can I use passport-google-oauth ?
Hm, this is really a comment rather than an answer, but I can’t put newlines in those:
it has to be the web-side Clent ID that goes in the put_my_clientid_here spot
if GoogleAuthUtil.getToken() gives you a String withou throwing an Exception, it really ought to be valid. When you hit tokeninfo, did you use ...tokeninfo?id_token=<857-byte-value-here>
if you’re a rubyist, grab the google-id-token gem and see if it can validate your 857-byte token.
If you just want to read the contents of the data returned by GoogleAuthUtil.getToken then the process is very simple. The returned data is simply a JWT. So all you'd have to do is split the data by the . character, and then base64 (url) decode each piece.
It gets slightly more complicated if you want you want to verify the message's authenticity. Simply use your favorite crypto library to do the verification. The 3rd component of the JWT is the signature of the data and the Google certs are publicly available; that's all you need to verify the message.
For a week I have been looking into how to validate GoogleAuthUtil tokens received in Android Client application at Node.js server using passport.js
Finally I came across passport-google-token passport strategy which perfectly performs the task.
https://www.npmjs.com/package/passport-google-token
More details are present in the above link.
The official node SDK lets you do that now.
Here's the link: https://github.com/google/google-auth-library-nodejs/blob/master/lib/auth/oauth2client.js#L384
I'm not too familiar with the details of how Android works with respect to handing a token from the device to the server. My general impression, however, is that you don't go through the typical web-based OAuth dance. Instead, you directly call the "user info" endpoint, which will return the info corresponding to the user who holds the token, or reject the request if the token is invalid. There's some discussion on this related question:
validating Android's authToken on third party server
In effect, the token becomes a secret that is shared between both the device and your server, so its important to protect it.
There are a couple strategies for Facebook and Twitter that were developed to do similar things using tokens from iOS devices:
https://github.com/drudge/passport-twitter-token
https://github.com/drudge/passport-facebook-token
You can take some inspiration from them and tweak it to talk to Google's endpoints. Let me know how this turns out. I'd love to see a similar "passport-google-token" strategy, so if you implement one, let me know and I'll link to it!

Categories

Resources