{"id":265009,"date":"2024-11-21T08:05:57","date_gmt":"2024-11-21T08:05:57","guid":{"rendered":"https:\/\/michigandigitalnews.com\/index.php\/2024\/11\/21\/effortless-account-restoration-for-android-apps\/"},"modified":"2025-06-25T17:10:25","modified_gmt":"2025-06-25T17:10:25","slug":"effortless-account-restoration-for-android-apps","status":"publish","type":"post","link":"https:\/\/michigandigitalnews.com\/index.php\/2024\/11\/21\/effortless-account-restoration-for-android-apps\/","title":{"rendered":"Effortless account restoration for Android apps"},"content":{"rendered":"<p> [ad_1]<br \/>\n<\/p>\n<div>\n<meta content=\"https:\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEiFNDf69dCL-P2rn6PajockzNlxC57Z9hy3TaBi4Mi66aoKjamiB3M_nfk1CoSLKSieFcRSJbywsSfcEgvHNAhs3yc8K792Ig5r_lerGg4qL3n1Rb6_Xa0UHXdlHlVFwujegymT5esaB3hBVHS9u113MrDLEYIYda6O1dnQ8UNGTY0E5eiEuDiBSXUY_W4\/s1600\/Restore-Credentials-Feature.png\" name=\"twitter:image\"\/><br \/>\n<img decoding=\"async\" src=\"https:\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEiFNDf69dCL-P2rn6PajockzNlxC57Z9hy3TaBi4Mi66aoKjamiB3M_nfk1CoSLKSieFcRSJbywsSfcEgvHNAhs3yc8K792Ig5r_lerGg4qL3n1Rb6_Xa0UHXdlHlVFwujegymT5esaB3hBVHS9u113MrDLEYIYda6O1dnQ8UNGTY0E5eiEuDiBSXUY_W4\/s1600\/Restore-Credentials-Feature.png\" style=\"display: none;\"\/><\/p>\n<p>\n<em>Posted by <a href=\"https:\/\/x.com\/NeelanshSahai\" target=\"_blank\" rel=\"noopener\">Neelansh Sahai<\/a> &#8211; Developer Relations Engineer <\/em>\n<\/p>\n<p><a href=\"https:\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEgaUCM7kC2VqW2Qj6AARAvYVJeHB1LuJfEdWyq5Mnti-YWlGWUAR32PkCHbobrLOcX3bZC-ew0hXmMcttv-Xg0fC9xgCyEMNQmNwZfhDpRnksMLANOAYJuTpvpczK39FddpBXFiZiErz31ohyphenhyphen3kO2q3SzfSJEei3Ohpn8o04w0GaSFEneNRwHIKrs89-Po\/s1600\/Restore-Credentials-Banner.png\"><img decoding=\"async\" border=\"0\" data-original-height=\"800\" data-original-width=\"100%\" src=\"https:\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEgaUCM7kC2VqW2Qj6AARAvYVJeHB1LuJfEdWyq5Mnti-YWlGWUAR32PkCHbobrLOcX3bZC-ew0hXmMcttv-Xg0fC9xgCyEMNQmNwZfhDpRnksMLANOAYJuTpvpczK39FddpBXFiZiErz31ohyphenhyphen3kO2q3SzfSJEei3Ohpn8o04w0GaSFEneNRwHIKrs89-Po\/s1600\/Restore-Credentials-Banner.png\"\/><\/a><\/p>\n<p>Did you know that, on average, 40% of the people in the US reset or replace their smartphones <a href=\"https:\/\/www.statista.com\/statistics\/619788\/average-smartphone-life\/\" target=\"_blank\" rel=\"noopener\">every year<\/a>? This frequent device turnover presents a challenge \u2013 and an opportunity \u2013 for maintaining strong user relationships. When users get a new phone, the friction of re-entering login credentials can lead to frustration, app abandonment, and churn.<\/p>\n<p>To address this issue, we&#8217;re introducing <a href=\"https:\/\/developer.android.com\/identity\/sign-in\/restore-credentials\" target=\"_blank\" rel=\"noopener\">Restore Credentials<\/a>, a new feature of Android\u2019s Credential Manager API. With Restore Credentials, apps can seamlessly onboard users to their accounts on a new device after they restore their apps and data from their previous device. This makes the transition to a new device effortless and fosters loyalty and long term relationships.<\/p>\n<p>On top of all this, there&#8217;s no developer effort required for the transfer of a restore key from one device to the other, as this process is tied together with the android system\u2019s backup and restore mechanism. However, if you want to login your users silently as soon as the restore is completed, you might want to implement <span style=\"color: #0d904f; font-family: Courier;\">BackupAgent<\/span> and add your logic in the <span style=\"color: #0d904f; font-family: Courier;\">onRestore<\/span> callback. The experience is delightful &#8211; users will continue being signed in as they were on their previous device, and they will be able to get notifications to easily access their content without even needing to open the app on the new device.<\/p>\n<p><image><a href=\"https:\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEioVNXeUrZrDWS0sg0gXLqSsl6Y8H59_QfiVjGzN_Z7BnHLsqXp9P4vkOYXX2l_G3Onicdfx7Clc6lj1NacegSIdHyumLG15aDdsBxiXFIOmZMo9A7I7bBHyHYOSeiITy5cD4qD8428fmUID2EZ6vq6ooZT7FzcE4Tjf_c8btK8CMr_dF75a7Fnqb-77_Q\/s1600\/Restore-Credentials-Feature%20%281%29.png\" target=\"_blank\" rel=\"noopener\"><\/p>\n<div style=\"text-align: center;\"><img decoding=\"async\" alt=\"An illustration the process of restoring app data and keys to a new device, highlighting automated steps and user interactions.  The top row shows a user signing into an app and a restore key being saved locally, while the bottom row shows the restore process on a new device.\" border=\"0\" id=\"imgCaption\" src=\"https:\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEioVNXeUrZrDWS0sg0gXLqSsl6Y8H59_QfiVjGzN_Z7BnHLsqXp9P4vkOYXX2l_G3Onicdfx7Clc6lj1NacegSIdHyumLG15aDdsBxiXFIOmZMo9A7I7bBHyHYOSeiITy5cD4qD8428fmUID2EZ6vq6ooZT7FzcE4Tjf_c8btK8CMr_dF75a7Fnqb-77_Q\/s16000\/Restore-Credentials-Feature%20(1).png\"\/><\/div>\n<p><\/a><imgcaption><center><em>click to enlarge<\/em><\/center><\/imgcaption><\/image><\/p>\n<p>Some of the benefits of the Restore Credentials feature include:<\/p>\n<ul>\n<ul>\n<li><b>Seamless user experience:<\/b> Users can easily transition to a new Android device.<\/li>\n<\/ul>\n<ul>\n<li><b>Immediate engagement:<\/b> Engage users with notifications or other prompts as soon as they start using their new device.<\/li>\n<\/ul>\n<ul>\n<li><b>Silent login with backup agent integration:<\/b> If you&#8217;re using a backup agent, users can be automatically logged back in after data restoration is complete.<\/li>\n<\/ul>\n<ul>\n<li><b>Restore key checks without backup agent integration:<\/b> If a backup agent isn&#8217;t being used, the app can check for a restore key upon first launch and then log the user in automatically.<\/li>\n<\/ul>\n<\/ul>\n<h3>How does Restore Credentials work?<\/h3>\n<p>The Restore Credentials feature enables seamless user account restoration on a new device. This process occurs automatically in the background during device setup when a user restores apps and data from a previous device. By restoring app credentials, the feature allows the app to sign the user back in without requiring any additional interaction.<\/p>\n<p>The credential type that\u2019s supported for this feature is called restore key, which is a public key compatible with <a href=\"https:\/\/fidoalliance.org\/passkeys\/\" target=\"_blank\" rel=\"noopener\">passkey \/ FIDO2<\/a> backends.<\/p>\n<p><image><a href=\"https:\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEh-sTZ9gUWdJF8GQaex0kGVdy0LSBwfOI9eC_iAozsGw-TaVhLLkUyGvTXqniDeYwy72qvrIVPqUcfODfh2onvm3Lz7GfqDwcvuxjh-lEBY-wF5a0F-_TiZ_8jsSbg9ZI5ROSq35WxWsYapt4LUcwHhUIz8xW4vTG-DqgjnIbPUDzMfgqzFva9vJPESSxo\/s1600\/image2.png\" target=\"_blank\" rel=\"noopener\"><\/p>\n<div style=\"text-align: center;\"><img decoding=\"async\" alt=\"A diagram shows the device-to-device and cloud backup restore processes for app data and restore keys between old and new devices.  Steps are numbered and explained within the diagram.\" border=\"0\" id=\"imgCaption\" src=\"https:\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEh-sTZ9gUWdJF8GQaex0kGVdy0LSBwfOI9eC_iAozsGw-TaVhLLkUyGvTXqniDeYwy72qvrIVPqUcfODfh2onvm3Lz7GfqDwcvuxjh-lEBY-wF5a0F-_TiZ_8jsSbg9ZI5ROSq35WxWsYapt4LUcwHhUIz8xW4vTG-DqgjnIbPUDzMfgqzFva9vJPESSxo\/s1600\/image2.png\"\/><\/div>\n<p><\/a><imgcaption><center><em>Diagram that depicts restoring an app data to a new device using a restore credential, including creating the credential, initiating a restore flow, and automatic user sign-in.<\/em><\/center><\/imgcaption><\/image><\/p>\n<h3>User flow<\/h3>\n<p>On the old device:<\/p>\n<ol>\n<li>If the current signed-in user is trusted, you can generate a restore key at any point after they&#8217;ve authenticated in your app. For instance, this could be immediately after login or during a routine check for an existing restore key.<\/li>\n<li>The restore key is stored locally and backed up to the cloud. Apps can opt-out of backing it up to the cloud.<\/li>\n<\/ol>\n<p>On the new device:<\/p>\n<ol>\n<li>When setting up a new device, the user can select one of the two options to restore data. Either they can restore data from a cloud backup, or can locally transfer the data. If the user transfers locally, the restore key is transferred locally from the old to the new device. Otherwise, if the user restores using the cloud backup, the restore key gets downloaded along with the app data from cloud backup to the new device.<\/li>\n<li>Once this restore key is available on the new device, the app can use it to log in the user on the new device silently in the background.<\/li>\n<\/ol>\n<blockquote><p><b>Note:<\/b> You should delete the restore key as soon as the user signs out. You don\u2019t want your user to get stuck in a cycle of signing out intentionally and then automatically getting logged back in.<\/p><\/blockquote>\n<h3>How to implement Restore Credentials<\/h3>\n<p>Using the <a href=\"https:\/\/developer.android.com\/jetpack\/androidx\/releases\/credentials\" target=\"_blank\" rel=\"noopener\">Jetpack Credential Manager<\/a> let you create, get, and clear the relevant Restore Credentials:<\/p>\n<ul>\n<ul>\n<li><b>Create a Restore Credential:<\/b> When the user signs in to your app, create a Restore Credential associated with their account. This credential is stored locally and synced to the cloud if the user has enabled Google Backup and end to end encryption is available. Apps can opt out of syncing to the cloud.<\/li>\n<\/ul>\n<ul>\n<li><b>Get the Restore Credential:<\/b> When the user sets up a new device, your app requests the Restore Credential from Credential Manager. This allows your user to sign in automatically.<\/li>\n<\/ul>\n<ul>\n<li><b>Clear the Restore Credential:<\/b> When the user signs out of your app, delete the associated Restore Credential.<\/li>\n<\/ul>\n<\/ul>\n<p>Restore Credentials is available through the Credential Manager Jetpack library. The minimum version of the Jetpack Library is <span style=\"color: #0d904f; font-family: Courier;\">1.5.0-beta01<\/span>, and the minimum GMS version is <span style=\"color: #0d904f; font-family: Courier;\">242200000<\/span>. For more on this, refer to the <a href=\"https:\/\/developer.android.com\/identity\/sign-in\/restore-credentials\" target=\"_blank\" rel=\"noopener\">Restore Credentials DAC page<\/a>. To get started, follow these steps:<\/p>\n<div style=\"background: #f8f8f8; overflow:auto;width:auto;border:0;\">\n<pre style=\"margin: 0; line-height: 125%\"><span style=\"color: #408080; font-style: italic\">\/\/ build.gradle.kts<\/span>\nimplementation(<span style=\"color: #BA2121\">\"androidx.credentials:credentials:1.5.0-beta01\"<\/span>)\n<\/pre>\n<\/div>\n<div style=\"background: #f8f8f8; overflow:auto;width:auto;border:0;\">\n<pre style=\"margin: 0; line-height: 125%\"><span style=\"color: #408080; font-style: italic\">\/\/ Fetch Registration JSON from server<\/span>\n<span style=\"color: #408080; font-style: italic\">\/\/ Same as the registrationJson created at the time of creating a Passkey<\/span>\n<span style=\"color: #408080; font-style: italic\">\/\/ See documentation for more info<\/span>\n<span style=\"color: #008000; font-weight: bold\">val<\/span> registrationJson = ... \n\n<span style=\"color: #408080; font-style: italic\">\/\/ Create the CreateRestoreCredentialRequest object<\/span>\n<span style=\"color: #408080; font-style: italic\">\/\/ Pass in the registrationJSON <\/span>\n<span style=\"color: #008000; font-weight: bold\">val<\/span> createRequest = CreateRestoreCredentialRequest(\n  registrationJson,\n  <span style=\"color: #408080; font-style: italic\">\/* isCloudBackupEnabled = *\/<\/span> <span style=\"color: #008000; font-weight: bold\">true<\/span>\n)\n<\/pre>\n<\/div>\n<ul>\n<ul>\n<blockquote><p><b>NOTE:<\/b> Set the <span style=\"color: #0d904f; font-family: Courier;\">isCloudBackupEnabled<\/span> flag to false if you want the <span style=\"color: #0d904f; font-family: Courier;\">restoreKey<\/span> to be stored locally and not in the cloud. It\u2019s set as <span style=\"color: #0d904f; font-family: Courier;\">true<\/span> by default<\/p><\/blockquote>\n<\/ul>\n<\/ul>\n<div style=\"background: #f8f8f8; overflow:auto;width:auto;border:0;\">\n<pre style=\"margin: 0; line-height: 125%\"><span style=\"color: #008000; font-weight: bold\">val<\/span> credentialManager = CredentialManager.create(context)\n\n<span style=\"color: #408080; font-style: italic\">\/\/ On a successful authentication create a Restore Key<\/span>\n<span style=\"color: #408080; font-style: italic\">\/\/ Pass in the context and CreateRestoreCredentialRequest object<\/span>\n<span style=\"color: #008000; font-weight: bold\">val<\/span> response = credentialManager.createCredential(\n    context,\n    createRestoreRequest\n)\n<\/pre>\n<\/div>\n<ul>\n<p>4. When the user sets up a new device, call the <span style=\"color: #0d904f; font-family: Courier;\">getCredential()<\/span> method on the <span style=\"color: #0d904f; font-family: Courier;\">CredentialManager<\/span> object.<\/p>\n<\/ul>\n<div style=\"background: #f8f8f8; overflow:auto;width:auto;border:0;\">\n<pre style=\"margin: 0; line-height: 125%\"><span style=\"color: #408080; font-style: italic\">\/\/ Fetch the Authentication JSON from server<\/span>\n<span style=\"color: #008000; font-weight: bold\">val<\/span> authenticationJson = ...\n\n<span style=\"color: #408080; font-style: italic\">\/\/ Create the GetRestoreCredentialRequest object<\/span>\n<span style=\"color: #008000; font-weight: bold\">val<\/span> options = GetRestoreCredentialOption(authenticationJson)\n<span style=\"color: #008000; font-weight: bold\">val<\/span> getRequest = GetCredentialRequest(Immutablelist.of(options))\n\n<span style=\"color: #408080; font-style: italic\">\/\/ The restore key can be fetched in two scenarios to <\/span>\n<span style=\"color: #408080; font-style: italic\">\/\/ 1. On the first launch of app on the device, fetch the Restore Key<\/span>\n<span style=\"color: #408080; font-style: italic\">\/\/ 2. In the onRestore callback (if the app implements the Backup Agent)<\/span>\n<span style=\"color: #008000; font-weight: bold\">val<\/span> response = credentialManager.getCredential(context, getRequest)\n<\/pre>\n<\/div>\n<p>If you&#8217;re using a backup agent, perform the <span style=\"color: #0d904f; font-family: Courier;\">getCredential<\/span> part within the <span style=\"color: #0d904f; font-family: Courier;\">onRestore<\/span> callback. This ensures that the app&#8217;s credentials are restored immediately after the app data is restored.<\/p>\n<ul>\n<p>5. When the user signs out of your app, call the <span style=\"color: #0d904f; font-family: Courier;\">clearCredentialState()<\/span> method on the <span style=\"color: #0d904f; font-family: Courier;\">CredentialManager<\/span> object.<\/p>\n<\/ul>\n<div style=\"background: #f8f8f8; overflow:auto;width:auto;border:0;\">\n<pre style=\"margin: 0; line-height: 125%\"><span style=\"color: #408080; font-style: italic\">\/\/ Create a ClearCredentialStateRequest object<\/span>\n<span style=\"color: #008000; font-weight: bold\">val<\/span> clearRequest = ClearCredentialStateRequest(<span style=\"color: #408080; font-style: italic\">\/* requestType = *\/<\/span> <span style=\"color: #666666\">1<\/span>)\n\n<span style=\"color: #408080; font-style: italic\">\/\/ On user log-out, clear the restore key<\/span>\n<span style=\"color: #008000; font-weight: bold\">val<\/span> response = credentialManager.clearCredentialState(clearRequest)\n<\/pre>\n<\/div>\n<h3>Conclusion<\/h3>\n<p>The <a href=\"https:\/\/developer.android.com\/identity\/sign-in\/restore-credentials\" target=\"_blank\" rel=\"noopener\">Restore Credentials<\/a> feature provides significant benefits, ensuring users experience a smooth transition between devices, and allowing them to log in quickly and easily through backup agents or restore key checks. For developers, the feature is straightforward to integrate and leverages existing passkey server-side infrastructure. Overall, Restore Credentials is a valuable tool that delivers a practical and user-friendly authentication solution.<\/p>\n<p><\/p>\n<p><em><\/p>\n<p>This blog post is a part of our series: Spotlight Week: Passkeys. We&#8217;re providing you with a wealth of resources through the week. Think informative blog posts, engaging videos, practical sample code, and more\u2014all carefully designed to help you leverage the latest advancements in seamless sign-up and sign-in experiences.<\/p>\n<p>With these cutting-edge solutions, you can enhance security, reduce friction for your users, and stay ahead of the curve in the rapidly evolving landscape of digital identity. To get a complete overview of what Spotlight Week has to offer and how it can benefit you, be sure to <a href=\"https:\/\/android-developers.googleblog.com\/2024\/11\/passkeys-spotlight-week.html\" target=\"_blank\" rel=\"noopener\">read our overview blog post<\/a>.<\/p>\n<p><\/em><\/p>\n<\/div>\n<p>[ad_2]<br \/>\n<br \/><a href=\"http:\/\/android-developers.googleblog.com\/2024\/11\/maintain-strong-user-relationships-with-restore-credentials.html\">Source link <\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>[ad_1] Posted by Neelansh Sahai &#8211; Developer Relations Engineer Did you know that, on average, 40% of the people in the US reset or replace<\/p>\n","protected":false},"author":1,"featured_media":265010,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"_uf_show_specific_survey":0,"_uf_disable_surveys":false,"footnotes":""},"categories":[146],"tags":[],"_links":{"self":[{"href":"https:\/\/michigandigitalnews.com\/index.php\/wp-json\/wp\/v2\/posts\/265009"}],"collection":[{"href":"https:\/\/michigandigitalnews.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/michigandigitalnews.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/michigandigitalnews.com\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/michigandigitalnews.com\/index.php\/wp-json\/wp\/v2\/comments?post=265009"}],"version-history":[{"count":0,"href":"https:\/\/michigandigitalnews.com\/index.php\/wp-json\/wp\/v2\/posts\/265009\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/michigandigitalnews.com\/index.php\/wp-json\/wp\/v2\/media\/265010"}],"wp:attachment":[{"href":"https:\/\/michigandigitalnews.com\/index.php\/wp-json\/wp\/v2\/media?parent=265009"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/michigandigitalnews.com\/index.php\/wp-json\/wp\/v2\/categories?post=265009"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/michigandigitalnews.com\/index.php\/wp-json\/wp\/v2\/tags?post=265009"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}