how to prevent APNS device token redundancy in database - ios

I am using apns notification for my app, and for this i am storing the apns device token in my sql database.
The issue is that every time the user deletes or installs the app, it generates a new device token and this gets stored in the database, since the same user can have multiple devices, I cant update the token for that user and a new record gets created. this has let to many records for the same device and same user. it might lead to performance issue later.
Please help. How do I fix the issue storing multiple tokens for same user.

Sorry for replying late, we fixed the issue by running another job which used to delete APNS token stored in database other than the latest one.
Our database stored APNS tokens for each user and each device. Depending upon these uniqueness. only latest tokens for each device is kept in database to prevent multiple notification on same device.
another solution is to use upset (insert or update), if any device already has a token then update the same with new one or insert.
I feel IOS should provide reliable API to handle this. The present Delete token API is not reliable.

Related

Is it acceptable to send APNS device token each time with user request instead of registering user?

I have iOS application where new data arrives each hour on server.
When new data arrives, I would like to notify user if there is something of interest for him, based on his alert definitions.
I learned that only way to achieve that is APNS (Background tasks are not an option for regular precise waking up and fetching data so far I can tell after reading a lot).
I don't want to add registration/login requirements for user.
Is it possible and aligned with Apple standards to retrieve device token and send it to server each time with each alert request created by user, so that I can notify him/her by push notification once it is fulfilled?
So I can pair device token with alert request in database on server.
I don't want to implement apps feature and to go through effort of implementing APNS both client and server side only to get application rejected by Apple. Therefore, any reference to if it is possible or not, personal experience or working solution proposal is much appreciated.
Unfortunately, iOS uses a UUID as "device token" and it changes frequently and randomly (to protect privacy) so unless your application handles users one way or another, you won't be able to pair users with devices.
A solution might be that when your application installs for the first time and opens, you generate a unique id, it can be a UUID or some random string and save it to the keychain or if possible loses are okay, just save it to userDefaults. Keychain persists between app install and even is the user switches phones and you can use this uuid as "user per device"

Preserving Keychain data during developer account migration

I am migrating our organisation's app to a new developer account, for internal reasons. I've learned that upon transferring the app to the new account, and after we release an update for the app from the new developer account, we will incur a one time loss of keychain data.
My concern is, that we cannot afford this loss of data. Due to security reasons and nature of the type of clients using the app.
So my question is 2 part;
1) Is there any way that I can prevent this keychain data loss?
2) If not, what are the alternate strategies I can use to prevent the users from getting logged out during this transition?
Assuming you're talking about a real, full App Transfer I don't think this is possible. Keychains are not just differentiated via the app ID, but also the organization's ID (or more precisely the organization's ID is part of an app ID). Since the app's ID de facto changes with a transfer, iOS will prevent it to look up its old keychain. Not even app groups get around this, as a group cannot consist of apps by different organizations AFAIK. Apple would need to implement a kind of exception to this for at least a certain "migration period", but I doubt that will ever happen (for security considerations).
The only way to circumvent a re-login so that the transferred app can save the credentials in its "new" keychain would be to first have an update for the old, not-yet transferred app and have it save the credentials elsewhere, then have the transferred app look them up from there. I'd strongly recommend against this for security reasons, but if you absolutely must do that, you could upload the credentials somewhere secure (via an encrypted connection, obviously, i.e. SSL). You might even be able to use shared web credentials for this, but I haven't looked into that too deeply, so I am not sure whether both apps can be configured to be associated with that website (they're coming from two different teams, after all, but it might be allowed).
Even then, some users might "miss" the update of the older app before the transfer (and update to the "new" one), then they would have to re-login anyways.
If you follow this idea, be aware that you're "moving around" users' private data in a new way! Considering the recent GDPR fuzz this might even have string legal implications, so check with your company's legal advisors about this, too!
1) There is no way your can prevent data loss, since the App ID Prefix has changed during app transfer TN2311 > A one-time loss in keychain data will occur if you switch your App ID prefix
2)
If you application utilizes Push Notification, you can use the APNs device tokens to remap the user account.
Once the new app is launched:
Send the device token to server
Find the username from your database
Generate a session token (add your own security design here)
Save username + the token in your new Keychain
For those who doesn't allow notification, just force them to relogin

Push notification, is it the device token all we need, or more?

I'm reading over this previous thread because I was having a problem converting the device token to something I could send in a POST. That problem is solved, and my token is being sent properly to the server, which we store in a user's account record.
That is all I need to do, right? If we notify using that token, it will go to that user, and only that user? Or am I missing something really critical here?
When you say 'user' do you mean that your app can have different users log in and out?
To handle this, you can set up a table to map user_id to push_token and device_id. You should also add an enabled flag to this map - which means the user is currently logged in on that device.
Conceptually, while a device has only one push token, it may have many users, and a user may have many devices.
When a user signs into your app on a device you send user_id, push_token and device_id and set enabled=TRUE in your table. If this user/device combo never existed, add to your table.
When a user signs out of your app on a device you send user_id and device_id and set enabled=FALSE in your table.
When an event occurs that would trigger a push to user with user_id then you can look up what push_tokens are associated to that user_id and enabled=TRUE. Then you can simply push to those tokens.
#dmorrow is right. In addition, you need to make a .pem certificate with the same app id to make server push notifications work, check this ANSWER

Register an iphone App in a web service

I had a look into a few airline apps around there. This posed some questions, I couldn't find an answer to and would like to ask you as well. My questions won't have any code but aim more at the procedural level of such applications.
The first thing I wondered: When I use an airline app for booking a ticket for example, I guess that my smartphone will be registered in a database on a web service somewhere. Usually the companies will send you push notifications for further updates. This would imply to me that the device token by the APNS is saved in a database table "devices" for example, such they could find my device later on and send me notifications.
To make my question clearer I think about the flow of the user that way:
Open airline app for first time
User is being asked if he will allow push notifications
User confirms
APNS is providing a device token
The web service of the airline will save that device token in their database
If an update is necessary, use the device token in the DB and send
an update to the client
That would be the "easy" way to identify my users by their device token. But what would be the "standard" way of keeping track of registered devices?
To build upon my first question, I would like to expand this example a little bit. Most of the airline apps have the feature within the app to save a ticket as a passbook pass. I we take into account that the user has already accepted push notifications for the app he would be registered and listed on the web server with a device token for future reference.
As far as I know, passkit will send a web request to the airline server that they would have to parse in order to communicate with the passkit server. But in this request contained is a push token requested by the passbook app to receive updates.
Now I would think, that you have two different device tokens for the same user? I don't think you just can use the existing device token for pushing messages to the client in the database?
So how do you solve such an issue? If you have a user in your database registered and the airline provides a ticket as passbook pass, how can passbook interact with this data correctly afterwards?
I hope I could make my point in my questions :)
Thank you
what would be the "standard" way of keeping track of registered devices?
Whenever user starts your app you will get a callback
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken{
// associate device token with your username and send this to your server
}
Please note that device token keeps changing . From Apple docs
you cannot save a device token and use it for future reference. You need to update it for every run. Your server need to sync it's database of tokens.
Edit ..
Flow of user
To make my answer clearer I think about the flow of the user that way:
Open airline app
User is being asked if he will allow push notifications
User confirms
You provide device token and username to your server.
If your server now needs to send push notification it uses the most recent token and
send it to APN.

APNs duplicate tokens

We have a push notification server which holds the data (device tokens) for several different applications. With Apple wanting to stop people using the UDID as identifier, I was looking into changing this server so that it does not rely on UDIDs to identify devices any longer.
I understand that the tokens returned by APNs are not globally unique, but rather unique per device. However, when going through our database, I noticed that there are several cases (a few hundred on 750k+ registrations) where the same token is used for different devices.
So I'm trying to figure out what's causing this. At this point, I see 2 possibilities:
There is an obscure bug in our server registration handling somewhere
Apple recycles these device tokens (perhaps after a device reset?). We always store the last time a certain device registered, and I noticed that there are always at least several days between registrations of different devices with the same token. As far as I can tell, there are no tokens that are concurrently used by different devices.
I would really appreciate it if someone could shed some light on this.
What we know is that Apple tells us to use the Device Token to push notifications to a device. So, as long as you are:
Querying the APNs for a new device token every time the application is launching and registering it in your database
Querying the Feedback service for inactive devices and purging them from your database
... you are doing what Apple is expecting you to do.
However, I do suspect that there may be a bug in your registration code because 100/750k is a pretty high conflict rate. Considering these device tokens are used to push notifications, a lot of people would be complaining about receiving notifications that don't belong to them...

Resources