{"_id":"5876c3601a6b5b3900a5b339","version":{"_id":"55e67aab9cc7c62b00c4a1ed","project":"55e67aaa9cc7c62b00c4a1ea","__v":10,"createdAt":"2015-09-02T04:27:23.612Z","releaseDate":"2015-09-02T04:27:23.612Z","categories":["55e67aac9cc7c62b00c4a1ee","55e67b5556007d23005fee7d","55e67b5dde6fef23009480ca","55e680efde6fef23009480db","55e6829485a9741900314e99","561c61b4ad272c0d00a892df","586c014c0abf1d0f000d04d4","58991d2ad207df0f0002186b","589b8e1fdbb7cd190026732c","58b8ca5e3265d70f001788d4"],"is_deprecated":false,"is_hidden":false,"is_beta":false,"is_stable":true,"codename":"","version_clean":"1.0.0","version":"1.0"},"category":{"_id":"55e67aac9cc7c62b00c4a1ee","version":"55e67aab9cc7c62b00c4a1ed","__v":3,"pages":["55e67aae9cc7c62b00c4a1f0","55e67bfd9cc7c62b00c4a1f5","55ecd59b54a67b1700edcf3c"],"project":"55e67aaa9cc7c62b00c4a1ea","sync":{"url":"","isSync":false},"reference":false,"createdAt":"2015-09-02T04:27:24.277Z","from_sync":false,"order":0,"slug":"getting-started","title":"Getting started"},"__v":0,"parentDoc":null,"user":"5825dece55b1060f00ec4134","project":"55e67aaa9cc7c62b00c4a1ea","updates":[],"next":{"pages":[],"description":""},"createdAt":"2017-01-11T23:44:32.832Z","link_external":false,"link_url":"","githubsync":"","sync_unique":"","hidden":false,"api":{"settings":"","results":{"codes":[]},"auth":"required","params":[],"url":""},"isReference":false,"order":1,"body":"If you are migrating from another push provider (or from your existing homegrown solution), you may want to import existing push enabled devices into Carnival. This can be done in multiple ways. This guide will help you understand the best path forward based on your app strategy and installed base.\n\n## Migrate users over time\nIf your timeframe for release allows so, you can migrate users over time. In this scenario, you implement Carnival alongside your current provider. This way, you can start registering devices into the platform and even message them using both push notifications and in-app messages. \n\nThis approach allows you to import only active app users while giving you the advantage of tracking up-to-date information about the user's activity and behavior. You can start creating audiences based on the attributes Carnival tracks out of the box, and you can also track custom events and user attributes.\n\nSince both providers share the same device token and push credentials, you can also use Carnival to message these users, or use a combination of both platforms until your cut off date from your legacy provider.\n\nWhen you're ready to fully migrate to Carnival, you can still import device tokens from users who have yet to upgrade to your Carnival enabled app. This way, you can still send these users a push notification, for example to invite them to update the app. For more information, see Force Update and  Token Migration later on this page.\n\n## Force update\n\nIf you wish, you can force all the users to update to a new version of the app. This is a common scenario for app developers releasing a new major release of their app. In this case, people opening a previous version of the app will receive a message prompting them to go to the App Store or Google Play to download the most updated version. This app migration is always communicated to the user at least a few weeks in advance.\n\nThis approach gives you a clear implementation path while reducing the fragmentation of app versions you will need to maintain. This scenario is ideal when you are releasing a major update, for example in conjunction with a UX refresh or when adding key functionalities to your app.\n\n## Token migration\n\nToken migration gives you the continuity to send Carnival push notifications to devices registered with another push provider. Push tokens are imported and assigned to temporary, anonymous devices. You can send push notifications to these devices as long as the push token is valid.\n\nWe highly recommend to carry over existing tokens as the last step of your Carnival integration, in close proximity to the release of your Carnival-enabled app to the stores.\n[block:callout]\n{\n  \"type\": \"info\",\n  \"title\": \"Push notifications only\",\n  \"body\": \"Importing tokens will allow you to send push notifications only. You can start sending in-app messages and in-app notifications once your users update to the Carnival SDK.\"\n}\n[/block]\n## How does it work\nIn order to migrate and import push tokens into Carnival, you will need to provide us with a list of existing push tokens. We can also import any custom attributes related to this push token, according [to our format](doc:csv-format-for-push-token-import-into-carnival). As part of the import process, we also add a custom attribute to each device indicating that it was imported. Commonly, developers will pass us a CSV file with tokens and attributes.\n\nImporting these push tokens will create anonymous devices inside Carnival. These devices will have a Device ID, but will not report platform, model or location. They will also be reported as installed on the same day as import.\n[block:callout]\n{\n  \"type\": \"success\",\n  \"title\": \"Plan ahead\",\n  \"body\": \"Our team will need to review your existing token exports, and you will need to review and approve the import. Allow additional time in your project plan to make sure you have plenty of leeway during this process.\"\n}\n[/block]\n## Targeting imported devices\nYou will effectively be able to target imported devices in the usual way through the audience builder, based on the custom attributes that were imported. To proceed, create a new audience using Audience Builder and select the custom attributes that were imported. You can also use the app install date as an attribute, if you provided valid values for it.\n\nIf you integrated the Carnival SDK and released your app, you can send push notifications and in-app messages. Users who haven't upgraded the app can only receive push notifications.\n\n## Generating a new install from an imported device\nAs soon as the user updates the app to a version with the Carnival SDK, we will generate a new install within Carnival. Where possible, we attempt to uninstall the imported device, so that it will no longer be targetable and it will not appear in the Device Log.\n[block:callout]\n{\n  \"type\": \"info\",\n  \"body\": \"Please keep in mind that your app uninstalls will look a bit off for the first month or so that the apps are live, and this shouldn't be a cause of concern.  As imported users upgrade to the version of your apps with the Carnival SDK, the imported anonymous user will be uninstalled and re-installed as a known Carnival device.  The customer won't notice any difference, providing that you are carrying over their currently set attributes as they update to the new version.\"\n}\n[/block]\n## Migrating attributes from the app\nWhen this happens, you will need to migrate any custom attributes associated with the imported device to the new install. We suggest you add logic to set an attribute map on your new app's first run. Here's a suggested flow:\nBefore migrating to Carnival, create a copy of the attributes you are planning to migrate, and make sure they are mapped to a user or device. You can store a copy of the attributes on the cloud, on your servers, on a database/CRM, on local storage, or on any other location that allows you to effectively map attributes to a device. This needs to happen before you move your app to Carnival, and it will require to submit your app to the app store.\n\nHere's an example on how to store user preferences into the app's local storage:\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"UserDefaults.standard.set(\\\"Daniele\\\", forKey: \\\"first_name\\\")\\nUserDefaults.standard.set(\\\"gold\\\", forKey: \\\"loyalty_tier\\\")\\nUserDefaults.standard.set(1337, forKey: \\\"points\\\")\",\n      \"language\": \"swift\",\n      \"name\": \"iOS (Swift)\"\n    },\n    {\n      \"code\": \"NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];\\n[defaults setObject::::at:::\\\"Daniele\\\" forKey:@\\\"first_name\\\"];\\n[defaults setObject:@\\\"gold\\\" forKey:@\\\"loyalty_tier\\\"];\\n[defaults setInteger:1337 forKey:@\\\"points\\\"];\\n[defaults synchronize];\",\n      \"language\": \"objectivec\",\n      \"name\": \"iOS (Objective-C)\"\n    },\n    {\n      \"code\": \"SharedPreferences preferences = getSharedPreferences(\\\"LocalAttributes\\\", Context.MODE_PRIVATE);\\nSharedPreferences.Editor editor = preferences.edit();\\neditor.putString(\\\"first_name\\\", \\\"Daniele\\\");\\neditor.putString(\\\"loyalty_tier\\\", \\\"gold\\\");\\neditor.putInt(\\\"points\\\", 1337);\\neditor.commit();\",\n      \"language\": \"java\",\n      \"name\": \"Android (Java)\"\n    }\n  ]\n}\n[/block]\nAfter this, start importing your tokens and attributes into Carnival. This will give you the ability to target users with push notifications from Carnival while still retaining the ability to use the platform you're migrating from. You will not be able to use in-app messages or in-app notifications just yet.\n\nIn the meantime, integrate the Carnival SDK in your app. Add logic so that when the app start, it will retrieve your previously stored attributes, then create an attribute map to send attributes back to Carnival.\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"let attributes = CarnivalAttributes();\\nattributes.setString(UserDefaults.standard.string(forKey: \\\"first_name\\\"), forKey: \\\"first_name\\\")\\nattributes.setString(UserDefaults.standard.string(forKey: \\\"loyalty_tier\\\"), forKey: \\\"loyalty_tier\\\")\\nattributes.setInteger(UserDefaults.standard.integer(forKey: \\\"points\\\"), forKey: \\\"loyalty_tier\\\")\\n\\nCarnival.setAttributes(attributes) { (error) in\\n\\tif (error != nil) {\\n\\t\\tprint(\\\"An error occurred: \\\\(error)\\\")\\n\\t}\\n}\",\n      \"language\": \"swift\",\n      \"name\": \"iOS (Swift)\"\n    },\n    {\n      \"code\": \"CarnivalAttributes *attributes = [[CarnivalAttributes alloc] init];\\n[attributes setString:[defaults objectForKey:@\\\"first_name\\\"] forKey:@\\\"first_name\\\"];\\n[attributes setString:[defaults objectForKey:@\\\"loyalty_tier\\\"] forKey:@\\\"loyalty_tier\\\"];\\n[attributes setInteger:[defaults integerForKey:@\\\"points\\\"] forKey:@\\\"points\\\"];\\n[Carnival setAttributes:attributes withResponse:^(NSError * _Nullable error) {\\n    if (error) {\\n        NSLog(@\\\"Error - %@\\\", [error debugDescription]);\\n        // Add retry logic (optional)\\n    }\\n}];\",\n      \"language\": \"objectivec\",\n      \"name\": \"iOS (Objective-C)\"\n    },\n    {\n      \"code\": \"SharedPreferences preferences = getSharedPreferences(\\\"LocalAttributes\\\", Context.MODE_PRIVATE);\\nAttributeMap attributes = new AttributeMap();\\nattributes.putString(\\\"first_name\\\", preferences.getString(\\\"first_name\\\"));\\nattributes.putString(\\\"loyalty_tier\\\", preferences.getString(\\\"loyalty_tier\\\"));\\nattributes.putInt(\\\"points\\\", preferences.getInt(\\\"points\\\"));\\nCarnival.setAttributes(attributes, new Carnival.AttributesHandler() {\\n    @Override\\n    public void onSuccess() {\\n        // Add your confirmation logic, or clean up your SharedPreferences\\n    }\\n\\n    @Override\\n    public void onFailure(Error error) {\\n        // Add your error handling logic, such as a retry interval.\\n    }\\n});\",\n      \"language\": \"java\",\n      \"name\": \"Android (Java)\"\n    }\n  ]\n}\n[/block]\nThis will generate a new device with the previously set attributes, along with automatically tracked attributes such as device platform and model. It will also enable the user to also receive in-app messages and in-app notifications.\n\nYou can also choose to integrate Carnival ahead of time without registering for push notifications. This way, you can start registering devices and sending attributes while still using your current push provider. When you're ready, you can have your app register for push notifications with Carnival.","excerpt":"Migrating from other push or messaging services to Carnival","slug":"migrating-to-carnival","type":"basic","title":"Migrating to Carnival"}

Migrating to Carnival

Migrating from other push or messaging services to Carnival

If you are migrating from another push provider (or from your existing homegrown solution), you may want to import existing push enabled devices into Carnival. This can be done in multiple ways. This guide will help you understand the best path forward based on your app strategy and installed base. ## Migrate users over time If your timeframe for release allows so, you can migrate users over time. In this scenario, you implement Carnival alongside your current provider. This way, you can start registering devices into the platform and even message them using both push notifications and in-app messages. This approach allows you to import only active app users while giving you the advantage of tracking up-to-date information about the user's activity and behavior. You can start creating audiences based on the attributes Carnival tracks out of the box, and you can also track custom events and user attributes. Since both providers share the same device token and push credentials, you can also use Carnival to message these users, or use a combination of both platforms until your cut off date from your legacy provider. When you're ready to fully migrate to Carnival, you can still import device tokens from users who have yet to upgrade to your Carnival enabled app. This way, you can still send these users a push notification, for example to invite them to update the app. For more information, see Force Update and Token Migration later on this page. ## Force update If you wish, you can force all the users to update to a new version of the app. This is a common scenario for app developers releasing a new major release of their app. In this case, people opening a previous version of the app will receive a message prompting them to go to the App Store or Google Play to download the most updated version. This app migration is always communicated to the user at least a few weeks in advance. This approach gives you a clear implementation path while reducing the fragmentation of app versions you will need to maintain. This scenario is ideal when you are releasing a major update, for example in conjunction with a UX refresh or when adding key functionalities to your app. ## Token migration Token migration gives you the continuity to send Carnival push notifications to devices registered with another push provider. Push tokens are imported and assigned to temporary, anonymous devices. You can send push notifications to these devices as long as the push token is valid. We highly recommend to carry over existing tokens as the last step of your Carnival integration, in close proximity to the release of your Carnival-enabled app to the stores. [block:callout] { "type": "info", "title": "Push notifications only", "body": "Importing tokens will allow you to send push notifications only. You can start sending in-app messages and in-app notifications once your users update to the Carnival SDK." } [/block] ## How does it work In order to migrate and import push tokens into Carnival, you will need to provide us with a list of existing push tokens. We can also import any custom attributes related to this push token, according [to our format](doc:csv-format-for-push-token-import-into-carnival). As part of the import process, we also add a custom attribute to each device indicating that it was imported. Commonly, developers will pass us a CSV file with tokens and attributes. Importing these push tokens will create anonymous devices inside Carnival. These devices will have a Device ID, but will not report platform, model or location. They will also be reported as installed on the same day as import. [block:callout] { "type": "success", "title": "Plan ahead", "body": "Our team will need to review your existing token exports, and you will need to review and approve the import. Allow additional time in your project plan to make sure you have plenty of leeway during this process." } [/block] ## Targeting imported devices You will effectively be able to target imported devices in the usual way through the audience builder, based on the custom attributes that were imported. To proceed, create a new audience using Audience Builder and select the custom attributes that were imported. You can also use the app install date as an attribute, if you provided valid values for it. If you integrated the Carnival SDK and released your app, you can send push notifications and in-app messages. Users who haven't upgraded the app can only receive push notifications. ## Generating a new install from an imported device As soon as the user updates the app to a version with the Carnival SDK, we will generate a new install within Carnival. Where possible, we attempt to uninstall the imported device, so that it will no longer be targetable and it will not appear in the Device Log. [block:callout] { "type": "info", "body": "Please keep in mind that your app uninstalls will look a bit off for the first month or so that the apps are live, and this shouldn't be a cause of concern. As imported users upgrade to the version of your apps with the Carnival SDK, the imported anonymous user will be uninstalled and re-installed as a known Carnival device. The customer won't notice any difference, providing that you are carrying over their currently set attributes as they update to the new version." } [/block] ## Migrating attributes from the app When this happens, you will need to migrate any custom attributes associated with the imported device to the new install. We suggest you add logic to set an attribute map on your new app's first run. Here's a suggested flow: Before migrating to Carnival, create a copy of the attributes you are planning to migrate, and make sure they are mapped to a user or device. You can store a copy of the attributes on the cloud, on your servers, on a database/CRM, on local storage, or on any other location that allows you to effectively map attributes to a device. This needs to happen before you move your app to Carnival, and it will require to submit your app to the app store. Here's an example on how to store user preferences into the app's local storage: [block:code] { "codes": [ { "code": "UserDefaults.standard.set(\"Daniele\", forKey: \"first_name\")\nUserDefaults.standard.set(\"gold\", forKey: \"loyalty_tier\")\nUserDefaults.standard.set(1337, forKey: \"points\")", "language": "swift", "name": "iOS (Swift)" }, { "code": "NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];\n[defaults setObject:@\"Daniele\" forKey:@\"first_name\"];\n[defaults setObject:@\"gold\" forKey:@\"loyalty_tier\"];\n[defaults setInteger:1337 forKey:@\"points\"];\n[defaults synchronize];", "language": "objectivec", "name": "iOS (Objective-C)" }, { "code": "SharedPreferences preferences = getSharedPreferences(\"LocalAttributes\", Context.MODE_PRIVATE);\nSharedPreferences.Editor editor = preferences.edit();\neditor.putString(\"first_name\", \"Daniele\");\neditor.putString(\"loyalty_tier\", \"gold\");\neditor.putInt(\"points\", 1337);\neditor.commit();", "language": "java", "name": "Android (Java)" } ] } [/block] After this, start importing your tokens and attributes into Carnival. This will give you the ability to target users with push notifications from Carnival while still retaining the ability to use the platform you're migrating from. You will not be able to use in-app messages or in-app notifications just yet. In the meantime, integrate the Carnival SDK in your app. Add logic so that when the app start, it will retrieve your previously stored attributes, then create an attribute map to send attributes back to Carnival. [block:code] { "codes": [ { "code": "let attributes = CarnivalAttributes();\nattributes.setString(UserDefaults.standard.string(forKey: \"first_name\"), forKey: \"first_name\")\nattributes.setString(UserDefaults.standard.string(forKey: \"loyalty_tier\"), forKey: \"loyalty_tier\")\nattributes.setInteger(UserDefaults.standard.integer(forKey: \"points\"), forKey: \"loyalty_tier\")\n\nCarnival.setAttributes(attributes) { (error) in\n\tif (error != nil) {\n\t\tprint(\"An error occurred: \\(error)\")\n\t}\n}", "language": "swift", "name": "iOS (Swift)" }, { "code": "CarnivalAttributes *attributes = [[CarnivalAttributes alloc] init];\n[attributes setString:[defaults objectForKey:@\"first_name\"] forKey:@\"first_name\"];\n[attributes setString:[defaults objectForKey:@\"loyalty_tier\"] forKey:@\"loyalty_tier\"];\n[attributes setInteger:[defaults integerForKey:@\"points\"] forKey:@\"points\"];\n[Carnival setAttributes:attributes withResponse:^(NSError * _Nullable error) {\n if (error) {\n NSLog(@\"Error - %@\", [error debugDescription]);\n // Add retry logic (optional)\n }\n}];", "language": "objectivec", "name": "iOS (Objective-C)" }, { "code": "SharedPreferences preferences = getSharedPreferences(\"LocalAttributes\", Context.MODE_PRIVATE);\nAttributeMap attributes = new AttributeMap();\nattributes.putString(\"first_name\", preferences.getString(\"first_name\"));\nattributes.putString(\"loyalty_tier\", preferences.getString(\"loyalty_tier\"));\nattributes.putInt(\"points\", preferences.getInt(\"points\"));\nCarnival.setAttributes(attributes, new Carnival.AttributesHandler() {\n @Override\n public void onSuccess() {\n // Add your confirmation logic, or clean up your SharedPreferences\n }\n\n @Override\n public void onFailure(Error error) {\n // Add your error handling logic, such as a retry interval.\n }\n});", "language": "java", "name": "Android (Java)" } ] } [/block] This will generate a new device with the previously set attributes, along with automatically tracked attributes such as device platform and model. It will also enable the user to also receive in-app messages and in-app notifications. You can also choose to integrate Carnival ahead of time without registering for push notifications. This way, you can start registering devices and sending attributes while still using your current push provider. When you're ready, you can have your app register for push notifications with Carnival.