APNS with Firebase version 3 - ios

I've set up Firebase to send push notifications to users of my app. However, I'm not sure what's best practice regarding user-to-user communication, such as chat clients. Should I get the device token at each startup of the app and use that for sending, or should I create a new topic for each "chatroom" that both parties are required to subscribe to? For instance when accepting a chat request.
If the first option is the best, how does this work? If the device is assigned a new token upon app startup, how can I be sure a given ID points to a specific device? The whole concept seems fragile - but could someone guide me to the most efficient solution?
I'm only looking to send chat messages / chat invites with push

Depending on the size and the privacy of the chatroom you can choose between using:
topics made for big groups, and without protections on joining / leaving
device tokens that you need to store in your server implementation.
On the plus side they allow you to control the who is receiving the
messages, and to send messages to individual device.
The device token does not change every startup.
It is created when the application is launched for the first time, and can be updated in special cases. When the token change (again, this is rare) the FirebaseInstanceIdService.onTokenRefresh() callback is called.
In a generic chat application you might want to:
first authenticate the user with your login system
upload to your server the mapping user-id > device-token
send messages to the users via the FCM server-side APIs.
Update to address one of the comments:
The server-side API allows to send the same message to multiple tokens in the same HTTP request. See registration_ids in https://firebase.google.com/docs/cloud-messaging/http-server-ref#downstream-http-messages-json
You should not use the server-side API in the client, because that would require you to add the API-KEY in the application which is a security issue (people could decompile the app and read the key)
The storage structure is up to you. For user-id > multiple-device-tokens a dictionary could work.
If the token are non reusable. So it's safe to send messages to expired token.
Token generation requires internet connectivity, so it could take some time.
To handle token after user registration see this question:
How to launch FCM ID Service only after a particular activity is triggered?

Related

Sending Notifications to user while app is in background

I've done lots of research on this from Firebase to App delegate but I don't understand a lot. I'm trying to send notifications to the user when someone else has posted something in my app - like on Instagram or social media post notifications. Can someone please point me in the right direction for how to do this? Thanks a lot in advance!
Overview
If you have setup your iOS app for Firebase Cloud Messaging (FCM), when the user first opens your app, the apps talks to the google servers and generated a token specific to that device.
What is a token?
The token is like a device identifier. You use that token to tell firebase which exact device you want it to send the notification to. (The token changes on uninstalling and reinstalling the app and may even on a restore).
On the backend
Now, you have to configure your app to send that token to your backend and store it as one of the tokens for the user currently logged in. (This should happen every time they login from that device, and you should remove that token from the server when the user logs out).
Whenever you need to send out a notification, you'll have to make a POST request to the FCM server. This POST request will contain the device token and the content of the notification, along with other authorization info. Detailed instructions are provided at
Send a Notification Message

Bluemix Push service security concern

We are using IBM Push-Notification service and Mobile-App-Security on our Bluemix app (serving iOS clients).
In order to send a push notification, our server sends a POST request to: https://mobile.ng.bluemix.net/push/v1/apps/{application-id}/messages
with the application secret in the Ibm-Application-Secret header (following the instructions here).
To initialize Mobile-App-Security SDK inside our app you need both the application-id and the application-secret - this means that the app itself must contain these values (as constant parameters or download it from a server). If a malicious user fetches these values using simple reverse-engineering, he would be able to send the same POST requests, i.e. send push notifications to other clients, right?
Shouldn't there be two application-secrets? One secret for the app (making it hard to fake registrations - i.e. require reverse-engineering) and one for the server (which allows to send notifications and should never be stored on client-side).
Is it possible to initialize the Mobile-App-Security iOS SDK without an application secret?
I understand your concern. To address all your questions:
-You must have the app secret on the Client side in order to authenticate with MAS and use the Push service (Push relies on MAS auth)
-We recommend implementing your own form of security to prevent a malicious user from easily obtaining the App Secret. For example, encrypting the file that stores the app secret, or just the app secret itself.
If you are looking for a more robust built-in level of security, I would recommend using the newer MobileFirst Services Starter, with support for Push and the Advanced Mobile Access service (AMA), which is currently only available for iOS 8.
A mobile device registers with its unique device id at the server running on Bluemix. If you don't trust a device, you could send a push notification with a key to this device and request it back. If you get this key back, the device has also registered at Google or Apple successfully.

Implementing Two Factor Authentication in iPad App

I'm planning introduce two factor authentication to my iPad application. Currently user login to my app using a username and password. That username and password is validate from the back end web server devloped using .Net. If user is authorize to login then he can access the iPad application.
Now I want to introduce two factor authentication to validate user. I want to know what are the options we have here. Since we have user’s phone no with us I was thinking of sending a passcode to his phone each time he tries to login to the iPad application. But iPad doesn’t support sending messages over the GSM/CDMA network. Is there a way to achieve this? (Thought about getting an SMS gateway from the local ISP and writing SMS a server. But it cost more) Third-party module will be ok.
Check google authenticator. https://code.google.com/p/google-authenticator/
I think it is quiet good for two-step authentication.
Here is source code for server side (it is on php but i think it is not big issue to convert it to .NET or another platform) https://github.com/chregu/GoogleAuthenticator.php
As I know it uses Time-based One-time Password Algorithm http://en.wikipedia.org/wiki/Time-based_One-time_Password_Algorithm
You can send an SMS to the mobile phone of the user with a code.
After that the user puts the code and the APP validates the code making a request to the server.
The SMS is sended after the user sucessful introduced the username/password.
Other option (less expansive) is to send that code by email.
You should try the google Authenticator
There are other's like https://www.gauthify.com, who offer this service.
You may be interested in looking in this StackOverflow Post.
I cannot fully express how much I am impressed by Twitter's recent TFA implementation, it is extremely convenient and (assuming they didn't botch the protocol) much more secure than many other forms of TFA.
Here's a description written by Wired.
But to summarize you activate a device for TFA and it generates a private (device)/ public (server) key pair. When you try to login after receiving correct username/password credentials the server sends a push notification to the application on any authorized devices encrypted with the public key and the application decrypts the nonce and sends the nonce back to the server and is given a session.
And of course as others have mentioned, there are prebuilt services you can use such as Google Authenticator, but they tend to be clunkier and there are concerns about SMS and TOTP security.
Two Factor Authentication means confirming something the user knows (their password) and something they have in their possession (like a physical key, a badge, or RSA key fob; the important part is it's a physical object other than what you are giving them access into). Sending a push of any kind to the iPad they are using to login to the app defeats the purpose and is no better than single factor (password only). Your only choices are:
Distribute an RSA key fob (or similar). Probably not an option because of the cost & management overhead associated.
Create an authenticator app that only works on a separate device than the iPad with your app on it (along the same lines as the Google Authenticator app). You can probably prevent the authenticator app being run on the iPad by registering a URI scheme for your protected app and trying to open it from the authenticator every time the authenticator is opened. If the protected app opens that means the user is trying to run both on the same device and the authenticator should not validate them.
Send a SMS to their registered phone with an authentication code. By using SMS here you're forcing the user to have both devices to be able to login, which is the key to TFA. Note that a creative user could register a Google Voice number (or similar VOIP with SMS app) on their iPad, thus circumventing the physical aspect of TFA.

Doubts on using Apple Passbook

Am trying to develop a coupon using Apple Passbook. My scenario is i have a web server from which i have to send the offers to iPhone as a Coupon. I tried to understand about the communication how happens between them, but not clear about it. Can anyone suggest me,
How can i send the offers from my web server to iPhone as passbook?
Where i have to store my data either in my database or anyway we have to store in iphone?
If user views a coupon sent by us, how the user can use the coupon?
How can i send the offers from my web server to iPhone as passbook?
The process is as follows:
Create a pass containing your webserviceURL and authenticationToken
Once the user adds the pass to Passbook, their device will register with your web service and provide you with a device id and device token.
Update your pass database with the new offer information
Send an empty push message to the device token (from step 2) using the certificate (passTypeIdentifier) from the pass
The device will receive the push and will contact your web service for a list of updated serials
Your web service returns the serial number(s) of the pass(es) that you wish to update
The device then request the updated pass(es)
Your web service sends the new pass(es)
See this document for details on the web service specification. Also note that your production web service must use https.
Where i have to store my data either in my database or anyway we have to store in iphone?
In your database. The iPhone will only hold the information necessary to display the pass (in the pass.json file). Your database will need to hold details such as the last updated time and the device id and device token. There is a sample database available as part of the ruby server example in Apple's Passbook Support Materials (Apple developer account required)
If user views a coupon sent by us, how the user can use the coupon?
That is entirely up to you - a passbook coupon is no different to a paper coupon. It is up to the pass issuer to decide how they wish to use it. In the most simple case, the issuer could scan the code, then send a request to update your database (with let's say 'status = redeemed'), your server then follows the steps above to push a new pass to the device showing the user that the pass has been redeemed.

Should APNS Tokens be encrypted?

So, I was wondering, since users send their APNS tokens to the APNS provider in order to receive push notifications, should the tokens be encrypted? Is SSL necessary?
From what I figure is that there is no real sensitive data in the token. If someone actually managed to sniff the token from a user, he still would have to obtain my push certificate. And if he managed to do that (he won't ;-)) all he could do is send spam notifications to this particular user. Is that correct? Or did I miss something?
Also, I assume that it's not possible to identify a device (or more importantly, its user) based on an APNS token?
So, I want to assure that, if someone sniffs a push notification registration from one of my clients (the registration contains the APNS token and the information the user is interested in, and the connection is unencryped so everything is readable in plain text) ...
he still has to obtain my push certificate to be able to bother my client in any way
he knows that someone is interested in this information, but has no way to identify who my client is
Can I rest assured?
Thanks in advance!
SSL is almost never a BAD idea. Lack of SSL means your users will be susceptible to all sorts of nastiness like DNS poisoning, man in the middle, or sniffing.
Maybe you're worried about the cost of an SSL cert, or the overhead on your servers? I don't know - but I'm just sayin' - probably worth considering if you're getting paid to provide some service or are collecting personally identifiable information.
Otherwise your points in the post were pretty much right on. The fact is someone would need your push certificate to send out those messages to those users.
Also, I assume that it's not possible to identify a device (or more
importantly, its user) based on an APNS token?
Prior to iOS 5, that ID was consistent across all apps - so aggregate stats companies were able to use the ID to identify a specific user somewhat... at least to know "this is the same person". But that changed recently, and it's now a random per-app ID.

Resources