I am successfully fetching Apple APNS feedback data via PHP. The structure that I am getting (after some processing) looks something like this:
timestamp
device
You should store devices with their device token data, and then you can find these devices according to their device tokens. You might use device token for identifier each device. Than would be easy to find and change their statuses into your db.
@fyasar,
So your recommendation is to store the device token against device id(or some key). When a feedback is received for a device token, remove that device token row from DB, right? If have understood right, that wouldn't work in scenario were a user installs app, uninstalls it and then installs it again all with in a short duration and the feedback service was queried only after all this happened. In this case, if timestamp in feedback is not considered, device token will be removed which is incorrect as user has again installed the app and reregistered for push notification.
My question is this, as suggested in apple doc and many blogs, on registration, when device token is persisted, timestamp has to be persisted along with it. What time zone's ISO time should be persisted or what is the time zone on which feedback service returns the timestamp.
The timestamp is the crucial element here. The timestamp sent by Apple indicates the last time the push service attempted to deliver a message to the device and found the app to be uninstalled. If the device has re-registered with your service since then there is no need to delete it.
Therefore, every single time your app loads and sends the token to your service, you should log the time in your data store. When you run feedback you should check the time from Apple and compare it to the time you last received an update from the app on the device. If the time Apple sends is newer then the time you received an updated then you should delete (or disable) the device. If the time from Apple is earlier then you do not need to delete it because the user has reinstalled the device since Apple last tried to deliver.
neat explanation @argon, however I have another question about the timestamp.
Every time when an app enables push notification, the device token is sent to the server. Should I taken the timestamp from my server as to be persisted along with device token as didRegisterForRemoteNotificationsWithDeviceToken only gives deviceToken and not time. If my server runs in different timezone and APNS is running at different timezone, then the registration time stored( along with device token) cannot be compared with timestamp received from APNS feedback to check the sequence of register -> uninstall -> reregister.
I presume the APNS feedback timestamp is in UTC and the timestamp the server stores along with device token has to be converted to UTC before storing the ISO timestamp. This way both the timestamp will be in same timezone and diff check will be consistent.
please clarify
All devices given by feedback are 'failed' and should be removed. No feedback means no devices should be removed. It's covered over on the Apple Documentation:
Apple APN Documentation
A timestamp (as a four-byte time_t value) indicating when APNs determined that the app no longer exists on the device. This value, which is in network order, represents the seconds since 12:00 midnight on January 1, 1970 UTC.
you can compare it with your table's last insert time and then remove the invalid token from db, In my case i am using mysql and php for sever side
$sql="SELECT insert_time from device_tokens ORDER BY insert_time DESC LIMIT 1";
it will return last updated time from db and then i just convert it into epoch timestamp by using
$sql1="SELECT UNIX_TIMESTAMP(' $timestamp')";
and finally i just compare it with apns feedback timestamp like this
if($inactive_Timestamp>$dbTime_stamp)
{
foreach ($apnsfeedback_tokens as $key => $value) {
# code...
$inactive_Token=$value['devtoken'];
$sql= "DELETE FROM device_tokens WHERE device_token='$inactive_Token'";
if ($conn->query($sql) === TRUE) {
echo "Record deleted successfully";
} else {
echo "Error deleting record: " . $conn->error;
}