- Overview
- Example Mobile Push Object
- Import Code Breakdown
- Skip devices without device token and OS
- Check if device token is associated with an existing contact record
- Insert new device data
- Cordial's Mobile SDK Alongside Other Providers
Overview
When Cordial's mobile SDK is initialized in your app, it automatically captures the device data necessary for device identification and routing of push notifications to your contacts. One of the most reliable ways to obtain up-to-date mobile device data is through the SDK while contacts interact with your app. But this method relies on your contacts having the latest version of the app installed on their devices, which isn't a common occurrence for many app users.
To ensure that you can send push notifications to your existing contacts, no matter which version of the app they have installed, you can use Cordial's Data Automations and an externally hosted data file to migrate device data to Cordial.
We will break down the logic of a sample Smarty script that is designed to prepare device data from your import file and import it to your Cordial account.
Example Mobile Push Object
Mobile push channel object:
{ "channels": { "push": { "address": { "5c98d21q-b3o8-42bc-9dac-e9d3c00e34e1": { "app": "1.0.0-MobileApp", "os": "android", "pushEnabled": true, "sdk": "1.0", "token": "do4-_NCZRbiKTo_l-8jVKy...", "v": "10" } }, "subscribedAt": "2020-04-16T20:52:21+0000", "unsubscribedAt": "", "subscribeStatus": "subscribed" } } }
Parameter details
Parameter | Description |
---|---|
channels.push.address | A unique identifier for the registered device (deviceID). Cordial's mobile SDK generates this value when contacts begin using your app for the first time after SDK is initialized, but this value can also be generated using Smarty. Multiple unique devices can be associated with a single contact record. |
channels.push.address.deviceID.app | The version of your app installed on the device. |
channels.push.address.deviceID.os | Device operating system (iOS or Android). |
channels.push.address.deviceID.pushEnabled | Indicates whether push notifications are enabled (true of false). |
channels.push.address.deviceID.sdk | The version of Cordial's SDK in your app. |
channels.push.address.deviceID.token | APNS (Apple) or FCM (Android) issued device token. |
channels.push.address.deviceID.v | Device operating system version. |
channels.push.unsubscribedAt | The most recent date contact unsubscribed from the push channel. |
channels.push.subscribedAt | The most recent date contact subscribed to the push channel. |
channels.push.subscribeStatus | Contact's current push channel subscribe status. |
Import Code Breakdown
This is our sample Smarty code in its entirety. You can scroll the code box or copy its contents for easier viewing in a different application.
{* Sample Row: - token -> The Device Token (required) - device_type -> The Device Platform (required) - alias -> The Email Address (optional) - opt_in -> Are Push Notifications Enabled (optional) *} {*Set a few variables*} {$channelKey = 'push'} {$token = $dataRecord.token} {$device_type = $dataRecord.device_type} {$deviceId = null} {$device = null} {$waitForResult = true} {*If the token or device_type is empty, skip this record*} {if !empty($token) && !empty($device_type)} {if $utils->strContains("ios", $device_type, false)} {*For iOS tokens, we need to lowercase them before proceeding*} {$token = $token|lower} {/if} {*Search by token to see if the device already exists*} {$foundContact = $utils->getContactByDeviceToken($channelKey, $token)} {* If a contact was found, you can skip or perform other data operations on the record *} {if $foundContact} {*Do nothing as the device already exists, probably came in naturally via an app update with Cordial SDK*} {else} {*Device doesn't exist yet, we need to import it*} {*Generate a new DeviceID*} {$deviceId = $utils->generateUUID4()} {* Preparing a payload, required fields: 'os', 'pushEnabled', 'token', optional fields: 'sdk', 'app', 'v' *} {*Setting values to 0 for now to signal these were imported*} {$device = ['os' => $device_type, 'token' => $token, 'v' => '0', 'sdk' => '0', 'app' => '0']} {*If we aren't given a value for pushEnabled, we will default to true as we will get feedback on the next send*} {if isset($dataRecord.opt_in)} {$device['pushEnabled'] = $dataRecord.opt_in} {else} {$device['pushEnabled'] = true} {/if} {*Add the device to the devices array to upsert*} {$payload["channels.$channelKey.address"] = [$deviceId => $device]} {*Set the secondary key to create a cID + device contact*} {$pk = "{$channelKey}:{$token}"} {*If an email is provided, we will use that as the secondary key so it updates an existing contact if the email exists*} {if !empty($dataRecord.alias)} {$payload["channels.email.address"] = $dataRecord.alias} {$pk = "email:{$dataRecord.alias}"} {/if} {$c = $utils->upsertContact($payload, $pk, true)} {if $device['pushEnabled'] === true} {*Also call update contact to update the subscribe status if they are opted-in*} {$contact = $utils->setcontact("cID:{$c._id}")} {$c = $utils->updateContact(["channels.$channelKey.subscribeStatus" => "subscribed"], $waitForResult, true, true)} {/if} {/if} {/if}
Skip devices without device token and OS
Depending on how your import file was compiled, it may contain device data without the required device token and device OS values. A common reason these values may be missing is due to being removed by the previous push provider when your app is uninstalled from the contact's device.
{*If the token or device_type is empty, skip this record*} {if !empty($token) && !empty($device_type)}
Our script will skip device records without these values and continue uninterrupted.
Check if device token is associated with an existing contact record
Your import file could contain device data that already exists in Cordial if some of your contacts have been using a version of your app with Cordial's SDK installed. We are using the getContactByDeviceToken Smarty utility to check if any of the device tokens in the import file are associated with an existing contact record in your Cordial account.
{*Search by token to see if the device already exists*} {$foundContact = $utils->getContactByDeviceToken($channelKey, $token)} {* If a contact was found, you can skip or perform other data operations on the record *} {if $foundContact} {*Do nothing as the device already exists, probably came in naturally via an app update with Cordial SDK*}
Device data added via Cordial's SDK while contacts are using your app is usually current and may not need to be changed during migration. Our script does not update this data but you could perform any number of operations on the incoming data prior to updating existing records.
Insert new device data
This part of the script will insert new device data from the import file.
{else} {*Device doesn't exist yet, we need to import it*} {*Generate a new DeviceID*} {$deviceId = $utils->generateUUID4()} {* Preparing a payload, required fields: 'os', 'pushEnabled', 'token', optional fields: 'sdk', 'app', 'v' *} {*Setting values to 0 for now to signal these were imported*} {$device = ['os' => $device_type, 'token' => $token, 'v' => '0', 'sdk' => '0', 'app' => '0']} {*If we aren't given a value for pushEnabled, we will default to true as we will get feedback on the next send*} {if isset($dataRecord.opt_in)} {$device['pushEnabled'] = $dataRecord.opt_in} {else} {$device['pushEnabled'] = true} {/if} {*Add the device to the devices array to upsert*} {$payload["channels.$channelKey.address"] = [$deviceId => $device]}
To successfully insert new device data, the script will look for the required data fields within the import file. Some of the required values may be set by the script.
Required data fields:
Parmeter | Source |
---|---|
channels.push.address | Our script will generate unique deviceID values using the generateUUID4 Smarty utility. |
channels.push.address.deviceID.os | Import file. |
channels.push.address.deviceID.pushEnabled | Import file. If not provided, the script will default this value to true. |
channels.push.address.deviceID.token | Import file. |
pushEnabled
value to true does not set the push opt-in status of the actual device. Only contacts can opt-in and out of receiving push notifications by changing push settings on their device. This value is set to true so the next time you send a notification to those contacts, APNS or FCM will respond and verify if the device token is valid.The optional values for device OS version, SDK version and app version will default to 0 and can be updated at a later time as your contacts begin using the version of your app with Cordial's SDK initialized.
Use email address as secondary contact identifier:
Some of your records may contain an email address. When this is the case, our script will use the email value as the secondary contact key to identify and update contact records:
{*If an email is provided, we will use that as the secondary key so it updates an existing contact if the email exists*} {if !empty($dataRecord.alias)} {$payload["channels.email.address"] = $dataRecord.alias} {$pk = "email:{$dataRecord.alias}"} {/if} {$c = $utils->upsertContact($payload, $pk, true)}
Finally, if push notifications are enabled at the device level, our script will set contacts' subscription status at the push channel level to subscribed, ensuring contacts continue receiving push notifications:
{if $device['pushEnabled'] === true} {*Also call update contact to update the subscribe status if they are opted-in*} {$contact = $utils->setcontact("cID:{$c._id}")} {$c = $utils->updateContact(["channels.$channelKey.subscribeStatus" => "subscribed"], $waitForResult, true, true)} {/if} {/if} {/if}
Cordial's Mobile SDK Alongside Other Providers
Cordial's mobile SDK is capable of running alongside other SDKs on the same app. In this scenario, Cordial's SDK assumes more of a listener role, waiting for your instructions on when and how to handle push notifications and other events.
This is a reliable way to test the SDK installation as it lets you selectively allow the new SDK to handle device and event data. After some time of testing and reaching satisfactory integration results, you can transition to letting Cordial's mobile SDK handle push notifications and events automatically.
Learn more by accessing Cordial's mobile SDK developer documentation on GitLab:
Comments
0 comments
Please sign in to leave a comment.