<?xml version="1.0" encoding="utf-8"?><?xml-stylesheet type="text/xsl" href="atom.xsl"?>
<feed xmlns="http://www.w3.org/2005/Atom">
    <id>https://docs.alwinsden.com/articles</id>
    <title>alwinsDen.com Blog</title>
    <updated>2026-02-16T00:00:00.000Z</updated>
    <generator>https://github.com/jpmonette/feed</generator>
    <link rel="alternate" href="https://docs.alwinsden.com/articles"/>
    <subtitle>alwinsDen.com Blog</subtitle>
    <icon>https://docs.alwinsden.com/img/favicon.ico</icon>
    <entry>
        <title type="html"><![CDATA[Compose Previews - A Relaxed Development.]]></title>
        <id>https://docs.alwinsden.com/articles/compose-previews</id>
        <link href="https://docs.alwinsden.com/articles/compose-previews"/>
        <updated>2026-02-16T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Article No. 2 of the KMP series.]]></summary>
        <content type="html"><![CDATA[<div class="theme-admonition theme-admonition-info admonition_Yu28 alert alert--info"><div class="admonitionHeading_pWiJ"><span class="admonitionIcon_TSs0"><svg viewBox="0 0 14 16"><path fill-rule="evenodd" d="M7 2.3c3.14 0 5.7 2.56 5.7 5.7s-2.56 5.7-5.7 5.7A5.71 5.71 0 0 1 1.3 8c0-3.14 2.56-5.7 5.7-5.7zM7 1C3.14 1 0 4.14 0 8s3.14 7 7 7 7-3.14 7-7-3.14-7-7-7zm1 3H6v5h2V4zm0 6H6v2h2v-2z"></path></svg></span>info</div><div class="admonitionContent_Qh44"><p>This is the 2nd article in <strong>Understanding KMP</strong> series. Check out the previous one <a class="" href="https://docs.alwinsden.com/articles/kmp-gauth-multiplatform">here</a>!</p></div></div>
<p>Since the last post, a lot has changed on Project Dino, now renamed to <a href="https://github.com/alwinsDen/synapse-ai" target="_blank" rel="noopener noreferrer" class="">Synapse</a>. The intense white theme has shifted to (or more like in the process) adopting a bright, calm <span style="background:#F3DB00;color:#000000"> yellow</span> inspired from <a href="https://en.wikipedia.org/wiki/Pluribus_(TV_series)" target="_blank" rel="noopener noreferrer" class=""><em>Pluribus(2025)</em></a>. Last article's code references have been updated.</p>
<h3 class="anchor anchorTargetStickyNavbar_moQH" id="difference-between-preview--live-edits">Difference between @Preview &amp; Live Edits<a href="https://docs.alwinsden.com/articles/compose-previews#difference-between-preview--live-edits" class="hash-link" aria-label="Direct link to Difference between @Preview &amp; Live Edits" title="Direct link to Difference between @Preview &amp; Live Edits" translate="no">​</a></h3>
<p>Android Studio comes with manual/automated live edits, which, when a user makes changes to code, reflects those in a running emulator, without needing a full recompilation (*generally).</p>
<p>But what if the component is nested deep in a parent page that can be accessed only by authentication? What if it's visible only on a specific user action like a pop-up or a toast? So, if only using Live Edits, as a dev I would have to manually trigger these flows <em>every single time</em> or add in testing code to make this specific component always visible, not forgetting the huge resource footprint with a running emulator at all times.</p>
<p>The biggest sell of Previews? <em><strong>Isolation.</strong></em></p>
<p><img decoding="async" loading="lazy" alt="Synapse login preview" src="https://docs.alwinsden.com/assets/images/login_preview-a31d29844a35ef90cbbc8886ea92a274.png" width="3024" height="1898" class="img_GJyE">
The above shows login page in Preview mode. Since Previews are purely UX related feature, they don't have to rely on any kind of developer added component conditions.</p>
<h4 class="anchor anchorTargetStickyNavbar_moQH" id="some-things-that-compose-previews-resolves">Some things that Compose Previews resolves:<a href="https://docs.alwinsden.com/articles/compose-previews#some-things-that-compose-previews-resolves" class="hash-link" aria-label="Direct link to Some things that Compose Previews resolves:" title="Direct link to Some things that Compose Previews resolves:" translate="no">​</a></h4>
<ul>
<li class=""><strong>Build-and-Deploy Time Sink</strong>: No longer need to build your app to check the background changing from grey to turquoise. Previews reflect instantly.</li>
</ul>
<ul>
<li class="">
<p><strong>UI Edge Cases and States</strong>: As aforementioned, rather than hardcoding conditions to see error/success states of UI elements, these can be mocked with Previews, completely isolated from the core program.</p>
</li>
<li class="">
<p><strong>Display size fragmentation</strong>: Same screen, but want to see previews for desktops and tablets? Compose has got you covered.</p>
</li>
<li class="">
<p><strong>Helps you write better code</strong>: Hmm how? Well, since Previews are decoupled from the memory states &amp; backend, <strong>YOUR CODE</strong> needs to be clean enough to mock UI by just passing parameters. This comes with an incredible amount of reusability for the components.</p>
</li>
</ul>
<p>Let's go over some of these.</p>
<h3 class="anchor anchorTargetStickyNavbar_moQH" id="build-and-deploy-time-sink">Build-and-Deploy Time Sink<a href="https://docs.alwinsden.com/articles/compose-previews#build-and-deploy-time-sink" class="hash-link" aria-label="Direct link to Build-and-Deploy Time Sink" title="Direct link to Build-and-Deploy Time Sink" translate="no">​</a></h3>
<p>I deal with React for web at most times. So, cuz of this I never imagined that instant preview (or hot-reload) wasn't a gold standard on the Android side until very recently.</p>
<p>Let me show a very practical comparison.</p>
<p><img decoding="async" loading="lazy" alt="Synapse compile time preview" src="https://docs.alwinsden.com/assets/images/compile_time-9b4ea3390e854f219435ea88de1c9469.gif" width="3024" height="1964" class="img_GJyE"></p>
<p>Since Synapse supports a shared UI, I run most of my builds on iOS simulators (much smaller memory footprint). As shown, a simple color change needed a few seconds for rebuild &amp; installation (<em>though this would be much faster for android builds, but still needs the same process</em>).</p>
<p>What about <strong>Previews</strong>?</p>
<p><img decoding="async" loading="lazy" alt="Synapse preview time preview" src="https://docs.alwinsden.com/assets/images/preview_time-58bcc078297b32106f893e077e80d7d2.gif" width="3024" height="1964" class="img_GJyE"></p>
<p>Bamm! Instant because preview compilation doesn't care about the rest other than the element at hand.</p>
<h3 class="anchor anchorTargetStickyNavbar_moQH" id="ui-edge-cases-and-states">UI Edge Cases and States<a href="https://docs.alwinsden.com/articles/compose-previews#ui-edge-cases-and-states" class="hash-link" aria-label="Direct link to UI Edge Cases and States" title="Direct link to UI Edge Cases and States" translate="no">​</a></h3>
<p>For this, let's use simple test element. Synapse uses a bottom sheet <a href="https://github.com/alwinsDen/synapse-ai/blob/master/composeApp/src/commonMain/kotlin/com/alwinsden/dino/botInterface/components/BotTextField.kt#L149" target="_blank" rel="noopener noreferrer" class="">here</a> to cycle between selected models. Will be using the <code>ModelSelectionRadioMenu</code> compose element.</p>
<p>Since Previews are dev-only tools, we can keep them in separate preview modules. For this ModelSelectionRadioMenu, we create a <code>previews/componentsPreview.kt</code> file and mark the composable as private.</p>
<div class="language-kotlin codeBlockContainer_swyL theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_Lz3e"><pre tabindex="0" class="prism-code language-kotlin codeBlock_g3dV thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_zDA_"><span class="token-line" style="color:#F8F8F2"><span class="token annotation builtin" style="color:rgb(189, 147, 249)">@Preview</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">showBackground </span><span class="token operator">=</span><span class="token plain"> </span><span class="token boolean">true</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token annotation builtin" style="color:rgb(189, 147, 249)">@Composable</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">private</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">fun</span><span class="token plain"> </span><span class="token function" style="color:rgb(80, 250, 123)">ModelSelectionRadioMenuPreviewIndividual</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token function" style="color:rgb(80, 250, 123)">ModelSelectionRadioMenu</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        onClick </span><span class="token operator">=</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        state </span><span class="token operator">=</span><span class="token plain"> </span><span class="token function" style="color:rgb(80, 250, 123)">ModelSelectionParamDetails</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token comment" style="color:rgb(98, 114, 164)">/*a custom data class*/</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">            name </span><span class="token operator">=</span><span class="token plain"> </span><span class="token string-literal singleline string" style="color:rgb(255, 121, 198)">"Google Gemini"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">            description </span><span class="token operator">=</span><span class="token plain"> </span><span class="token string-literal singleline string" style="color:rgb(255, 121, 198)">"Advanced model from Google"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">            incomingType </span><span class="token operator">=</span><span class="token plain"> ModelDefinitions</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">GEMINI</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">name</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        currentSelection </span><span class="token operator">=</span><span class="token plain"> ModelDefinitions</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">GEMINI</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">name</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><br></span></code></pre></div></div>
<p>This renders:
<img decoding="async" loading="lazy" alt="lone render" src="https://docs.alwinsden.com/assets/images/lone_render-86eea45cd6b75f113e318ca615a8b4da.png" width="1766" height="464" class="img_GJyE"></p>
<p>Hmm, pretty basic right? What if I want to view the same with different string values?</p>
<p>Compose comes with this incredibly powerful method <code>@PreviewParameter</code>, which supports passing large datasets as parameter to the Preview parent of the composable. Basically think of it as passing a large list, and rendering a UI element for each. More on this <a href="https://developer.android.com/develop/ui/compose/tooling/previews#preview-data" target="_blank" rel="noopener noreferrer" class="">here</a>.</p>
<p>Now for the same <code>ModelSelectionRadioMenu</code></p>
<div style="display:grid;grid-template-columns:repeat(auto-fit, minmax(260px, 1fr));gap:1rem"><div><div class="language-kotlin codeBlockContainer_swyL theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_Lz3e"><pre tabindex="0" class="prism-code language-kotlin codeBlock_g3dV thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_zDA_"><span class="token-line" style="color:#F8F8F2"><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">private</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">class</span><span class="token plain"> ModelSelectPreviewProvider </span><span class="token operator">:</span><span class="token plain"> PreviewParameterProvider</span><span class="token operator">&lt;</span><span class="token plain">ModelSelectionParamDetails</span><span class="token operator">&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">override</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">val</span><span class="token plain"> values </span><span class="token operator">=</span><span class="token plain"> </span><span class="token function" style="color:rgb(80, 250, 123)">sequenceOf</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token function" style="color:rgb(80, 250, 123)">ModelSelectionParamDetails</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">            name </span><span class="token operator">=</span><span class="token plain"> </span><span class="token string-literal singleline string" style="color:rgb(255, 121, 198)">"Google Gemini"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">            description </span><span class="token operator">=</span><span class="token plain"> </span><span class="token string-literal singleline string" style="color:rgb(255, 121, 198)">"Advanced model from Google"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">            incomingType </span><span class="token operator">=</span><span class="token plain"> ModelDefinitions</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">GEMINI</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">name</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token function" style="color:rgb(80, 250, 123)">ModelSelectionParamDetails</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">            name </span><span class="token operator">=</span><span class="token plain"> </span><span class="token string-literal singleline string" style="color:rgb(255, 121, 198)">"Claude Opus"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">            description </span><span class="token operator">=</span><span class="token plain"> </span><span class="token string-literal singleline string" style="color:rgb(255, 121, 198)">"Advanced model from Anthropic"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">            incomingType </span><span class="token operator">=</span><span class="token plain"> ModelDefinitions</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">CLAUDE</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">name</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><br></span></code></pre></div></div></div><div><div class="language-kt codeBlockContainer_swyL theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_Lz3e"><pre tabindex="0" class="prism-code language-kt codeBlock_g3dV thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_zDA_"><span class="token-line" style="color:#F8F8F2"><span class="token comment" style="color:rgb(98, 114, 164)">/*botInterface/previews/componentsPreview.kt*/</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token annotation builtin" style="color:rgb(189, 147, 249)">@Preview</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">showBackground </span><span class="token operator">=</span><span class="token plain"> </span><span class="token boolean">true</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token annotation builtin" style="color:rgb(189, 147, 249)">@Composable</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">private</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">fun</span><span class="token plain"> </span><span class="token function" style="color:rgb(80, 250, 123)">ModelSelectionRadioMenuPreviewMultiple</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token annotation builtin" style="color:rgb(189, 147, 249)">@PreviewParameter</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">ModelSelectPreviewProvider</span><span class="token operator">::</span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">class</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> incomingClass</span><span class="token operator">:</span><span class="token plain"> ModelSelectionParamDetails</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token function" style="color:rgb(80, 250, 123)">ModelSelectionRadioMenu</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        onClick </span><span class="token operator">=</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"> tst </span><span class="token operator">-&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        state </span><span class="token operator">=</span><span class="token plain"> incomingClass</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        currentSelection </span><span class="token operator">=</span><span class="token plain"> ModelDefinitions</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">CLAUDE</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">name</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><br></span></code></pre></div></div></div></div>
<p>This renders:
<img decoding="async" loading="lazy" alt="multi-render" src="https://docs.alwinsden.com/assets/images/multi_render-4dd4a61d23d905afe8a4d7fb7f3fd61d.png" width="1616" height="624" class="img_GJyE"></p>
<h3 class="anchor anchorTargetStickyNavbar_moQH" id="display-size-fragmentation">Display size fragmentation<a href="https://docs.alwinsden.com/articles/compose-previews#display-size-fragmentation" class="hash-link" aria-label="Direct link to Display size fragmentation" title="Direct link to Display size fragmentation" translate="no">​</a></h3>
<p>One of the biggest advantages of Compose Multiplatform is writing UI code that works across phones, tablets, and desktops. But how do you verify your layouts look good on all these different screen sizes without constantly switching between devices or emulators?</p>
<p>Compose Preview comes with built-in device presets that let you preview your composables on different form factors. You can use predefined device types like <code>Devices.PIXEL_2_XL</code> for phones or <code>Devices.NEXUS_7</code> for tablets, but the real power lies in custom device specifications.</p>
<div class="language-kotlin codeBlockContainer_swyL theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_Lz3e"><pre tabindex="0" class="prism-code language-kotlin codeBlock_g3dV thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_zDA_"><span class="token-line" style="color:#F8F8F2"><span class="token annotation builtin" style="color:rgb(189, 147, 249)">@Preview</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    name </span><span class="token operator">=</span><span class="token plain"> </span><span class="token string-literal singleline string" style="color:rgb(255, 121, 198)">"Phone Portrait"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    device </span><span class="token operator">=</span><span class="token plain"> </span><span class="token string-literal singleline string" style="color:rgb(255, 121, 198)">"spec:width=411dp,height=891dp,dpi=420"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token annotation builtin" style="color:rgb(189, 147, 249)">@Preview</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    name </span><span class="token operator">=</span><span class="token plain"> </span><span class="token string-literal singleline string" style="color:rgb(255, 121, 198)">"Tablet Landscape"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    device </span><span class="token operator">=</span><span class="token plain"> </span><span class="token string-literal singleline string" style="color:rgb(255, 121, 198)">"spec:width=1280dp,height=800dp,dpi=213,orientation=landscape"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token annotation builtin" style="color:rgb(189, 147, 249)">@Preview</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    name </span><span class="token operator">=</span><span class="token plain"> </span><span class="token string-literal singleline string" style="color:rgb(255, 121, 198)">"Desktop"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    device </span><span class="token operator">=</span><span class="token plain"> </span><span class="token string-literal singleline string" style="color:rgb(255, 121, 198)">"spec:width=1920dp,height=1080dp,dpi=160"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token annotation builtin" style="color:rgb(189, 147, 249)">@Composable</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">private</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">fun</span><span class="token plain"> </span><span class="token function" style="color:rgb(80, 250, 123)">ResponsiveLayoutPreview</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token comment" style="color:rgb(98, 114, 164)">// Your composable here</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><br></span></code></pre></div></div>
<p>With Synapse being a KMP app targeting Android &amp; iOS, I can quickly iterate through different screen sizes to ensure the UI adapts correctly. No need to fire up multiple emulators or resize windows manually—just add multiple <code>@Preview</code> annotations with different device specs, and Android Studio will show all of them side-by-side in the preview panel.</p>
<p>Alternatively, triggering the <strong>Check UI</strong> mode on IntelliJ also generates screen previews.</p>
<p><img decoding="async" loading="lazy" alt="Generate multiple previews." src="https://docs.alwinsden.com/assets/images/preview_generate-24c7a7068f2c4f0a7fa2e831c93cf9e6.png" width="2976" height="1778" class="img_GJyE"></p>
<h3 class="anchor anchorTargetStickyNavbar_moQH" id="nice-but-how-does-preview-work">Nice! But how does @Preview work?<a href="https://docs.alwinsden.com/articles/compose-previews#nice-but-how-does-preview-work" class="hash-link" aria-label="Direct link to Nice! But how does @Preview work?" title="Direct link to Nice! But how does @Preview work?" translate="no">​</a></h3>
<p>This will need an article on its own. Will add it soon!</p>
<div class="theme-admonition theme-admonition-success admonition_Yu28 alert alert--success"><div class="admonitionHeading_pWiJ"><span class="admonitionIcon_TSs0"><svg viewBox="0 0 12 16"><path fill-rule="evenodd" d="M6.5 0C3.48 0 1 2.19 1 5c0 .92.55 2.25 1 3 1.34 2.25 1.78 2.78 2 4v1h5v-1c.22-1.22.66-1.75 2-4 .45-.75 1-2.08 1-3 0-2.81-2.48-5-5.5-5zm3.64 7.48c-.25.44-.47.8-.67 1.11-.86 1.41-1.25 2.06-1.45 3.23-.02.05-.02.11-.02.17H5c0-.06 0-.13-.02-.17-.2-1.17-.59-1.83-1.45-3.23-.2-.31-.42-.67-.67-1.11C2.44 6.78 2 5.65 2 5c0-2.2 2.02-4 4.5-4 1.22 0 2.36.42 3.22 1.19C10.55 2.94 11 3.94 11 5c0 .66-.44 1.78-.86 2.48zM4 14h5c-.23 1.14-1.3 2-2.5 2s-2.27-.86-2.5-2z"></path></svg></span>success</div><div class="admonitionContent_Qh44"><p>If you have any feedback or suggestions, please feel free to reach out to me.
Until then, consider starring the <a href="https://github.com/alwinsDen/synapse-ai" target="_blank" rel="noopener noreferrer" class="">project</a> and follow me on <a href="https://github.com/alwinsDen" target="_blank" rel="noopener noreferrer" class="">GitHub</a>.</p></div></div>]]></content>
        <author>
            <name>Alwin T Varghese</name>
            <uri>https://alwinsden.com</uri>
        </author>
        <category label="kotlin" term="kotlin"/>
        <category label="android" term="android"/>
        <category label="jetpack compose" term="jetpack compose"/>
        <category label="synapse" term="synapse"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[The KMP Way - GAuth for Android]]></title>
        <id>https://docs.alwinsden.com/articles/kmp-gauth-multiplatform</id>
        <link href="https://docs.alwinsden.com/articles/kmp-gauth-multiplatform"/>
        <updated>2026-02-03T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Article No. 1 of the KMP series.]]></summary>
        <content type="html"><![CDATA[<div class="theme-admonition theme-admonition-info admonition_Yu28 alert alert--info"><div class="admonitionHeading_pWiJ"><span class="admonitionIcon_TSs0"><svg viewBox="0 0 14 16"><path fill-rule="evenodd" d="M7 2.3c3.14 0 5.7 2.56 5.7 5.7s-2.56 5.7-5.7 5.7A5.71 5.71 0 0 1 1.3 8c0-3.14 2.56-5.7 5.7-5.7zM7 1C3.14 1 0 4.14 0 8s3.14 7 7 7 7-3.14 7-7-3.14-7-7-7zm1 3H6v5h2V4zm0 6H6v2h2v-2z"></path></svg></span>info</div><div class="admonitionContent_Qh44"><p>If new, checkout KMP architecture @ <a href="https://kotlinlang.org/multiplatform/" target="_blank" rel="noopener noreferrer" class="">KMP - Build Cross-platform</a></p></div></div>
<p>Since Compose Multi-platform combines the UI aspect for both <strong><em>iOS and Android</em></strong>, how do you implement Google authentication such that the UI code remains unified while maintaining the ideal authentication flow specific to these platforms in <img src="https://docs.alwinsden.com/img/kotlin-icon.png" alt="Kotlin" width="16" style="vertical-align:text-bottom"> Kotlin without using a KMP library?</p>
<h3 class="anchor anchorTargetStickyNavbar_moQH" id="kotlin-multiplatform-simplified">Kotlin Multiplatform simplified<a href="https://docs.alwinsden.com/articles/kmp-gauth-multiplatform#kotlin-multiplatform-simplified" class="hash-link" aria-label="Direct link to Kotlin Multiplatform simplified" title="Direct link to Kotlin Multiplatform simplified" translate="no">​</a></h3>
<p><img decoding="async" loading="lazy" alt="KMP architecture" src="https://docs.alwinsden.com/assets/images/kmp_client-718156ad235fabf813f1a44d7ea83495.png" width="1600" height="768" class="img_GJyE"></p>
<p>Refer to <a href="https://github.com/alwinsDen/synapse-ai" target="_blank" rel="noopener noreferrer" class="">Project Synapse code</a> to understand the archiecture. Basically, the UI layer of the application is shared between iOS and Android (composeApp module), with shared module acting as the common ground for business logic sharing between UI and backend server, while Ktor-based server rests in the server module. More <a href="https://kotlinlang.org/docs/multiplatform/multiplatform-discover-project.html" target="_blank" rel="noopener noreferrer" class="">here</a>.</p>
<h3 class="anchor anchorTargetStickyNavbar_moQH" id="the-google-auth">The Google Auth<a href="https://docs.alwinsden.com/articles/kmp-gauth-multiplatform#the-google-auth" class="hash-link" aria-label="Direct link to The Google Auth" title="Direct link to The Google Auth" translate="no">​</a></h3>
<p>There are two most common things in a Google authentication flow:</p>
<ol>
<li class="">The user manually signs in to the app by tapping the Sign in with Google button.</li>
<li class="">The user is automatically signed in, either from previously stored session state or via a bottom sheet that lets them pick from existing Google accounts.</li>
</ol>
<p>In this article, we explore implementation of Google authentication for Android while maintaining <strong>a common UI on a KMP app.</strong></p>
<div class="theme-admonition theme-admonition-warning admonition_Yu28 alert alert--warning"><div class="admonitionHeading_pWiJ"><span class="admonitionIcon_TSs0"><svg viewBox="0 0 16 16"><path fill-rule="evenodd" d="M8.893 1.5c-.183-.31-.52-.5-.887-.5s-.703.19-.886.5L.138 13.499a.98.98 0 0 0 0 1.001c.193.31.53.501.886.501h13.964c.367 0 .704-.19.877-.5a1.03 1.03 0 0 0 .01-1.002L8.893 1.5zm.133 11.497H6.987v-2.003h2.039v2.003zm0-3.004H6.987V5.987h2.039v4.006z"></path></svg></span>warning</div><div class="admonitionContent_Qh44"><p>For this app, the KMP implementation for Android is straight forward compared to iOS, in iOS we use cinterop library to communicate with native iOS Objective C code. Code <a href="https://github.com/alwinsDen/synapse-ai/tree/master/shared/src/iosMain/kotlin/authManager/ClickTriggerAuth.kt" target="_blank" rel="noopener noreferrer" class=""><strong>here</strong></a>.</p></div></div>
<h3 class="anchor anchorTargetStickyNavbar_moQH" id="setting-up-expect--actual-functions">Setting up, expect / actual functions<a href="https://docs.alwinsden.com/articles/kmp-gauth-multiplatform#setting-up-expect--actual-functions" class="hash-link" aria-label="Direct link to Setting up, expect / actual functions" title="Direct link to Setting up, expect / actual functions" translate="no">​</a></h3>
<p><img decoding="async" loading="lazy" alt="Compose Structure" src="https://docs.alwinsden.com/assets/images/compose-structure-3e8cae196f2c6ba9b175a64ef9e341cd.png" width="1044" height="1270" class="img_GJyE">
The above is the structure of our Compose Multiplatform app. The <code>commonMain</code> module contains the shared UI code for both Android and iOS platforms, while platform-specific implementations reside in the <code>androidMain</code> and <code>iosMain</code> modules.</p>
<p>In our implementation, the Sign in with Google UI interface will be shared, but the behaviour will be controlled by platform specific code.</p>
<div class="theme-admonition theme-admonition-info admonition_Yu28 alert alert--info"><div class="admonitionHeading_pWiJ"><span class="admonitionIcon_TSs0"><svg viewBox="0 0 14 16"><path fill-rule="evenodd" d="M7 2.3c3.14 0 5.7 2.56 5.7 5.7s-2.56 5.7-5.7 5.7A5.71 5.71 0 0 1 1.3 8c0-3.14 2.56-5.7 5.7-5.7zM7 1C3.14 1 0 4.14 0 8s3.14 7 7 7 7-3.14 7-7-3.14-7-7-7zm1 3H6v5h2V4zm0 6H6v2h2v-2z"></path></svg></span>info</div><div class="admonitionContent_Qh44"><p>Since this is not an introduction to expect / actual functions, if you are new to this, it is better to refer <a href="https://kotlinlang.org/docs/multiplatform/multiplatform-expect-actual.html" target="_blank" rel="noopener noreferrer" class="">compose documentation</a> on this.</p></div></div>
<p>The implementation of UI button in commonMain:</p>
<p>refer: <a href="https://github.com/alwinsDen/synapse-ai/blob/master/composeApp/src/commonMain/kotlin/com/alwinsden/dino/authentication/SignInMethod.kt" target="_blank" rel="noopener noreferrer" class="">SignInMethod.kt</a></p>
<div class="language-kotlin codeBlockContainer_swyL theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_Lz3e"><pre tabindex="0" class="prism-code language-kotlin codeBlock_g3dV thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_zDA_"><span class="token-line" style="color:#F8F8F2"><span class="token annotation builtin" style="color:rgb(189, 147, 249)">@Composable</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">fun</span><span class="token plain"> </span><span class="token function" style="color:rgb(80, 250, 123)">ClickableContinueWithGoogle</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">nonce</span><span class="token operator">:</span><span class="token plain"> String</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> handleReceivedGoogleTokenId</span><span class="token operator">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">String</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token operator">-&gt;</span><span class="token plain"> Unit</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">val</span><span class="token plain"> authProvider </span><span class="token operator">=</span><span class="token plain"> </span><span class="token function" style="color:rgb(80, 250, 123)">rememberGoogleAuthProvider</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">val</span><span class="token plain"> scope </span><span class="token operator">=</span><span class="token plain"> </span><span class="token function" style="color:rgb(80, 250, 123)">rememberCoroutineScope</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">var</span><span class="token plain"> loaderState </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">by</span><span class="token plain"> remember </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"> </span><span class="token function" style="color:rgb(80, 250, 123)">mutableStateOf</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token boolean">false</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token comment" style="color:rgb(98, 114, 164)">// Auto sign-in check on component mount</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token function" style="color:rgb(80, 250, 123)">LaunchedEffect</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">nonce</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">if</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">nonce </span><span class="token operator">==</span><span class="token plain"> Defaults</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">default</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">return</span><span class="token label symbol" style="color:rgb(248, 248, 242)">@LaunchedEffect</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        loaderState </span><span class="token operator">=</span><span class="token plain"> </span><span class="token boolean">true</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        authProvider</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">checkExistingCredentials</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">nonce</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token operator">?</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">let</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"> token </span><span class="token operator">-&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">            </span><span class="token function" style="color:rgb(80, 250, 123)">handleReceivedGoogleTokenId</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">token</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        loaderState </span><span class="token operator">=</span><span class="token plain"> </span><span class="token boolean">false</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token function" style="color:rgb(80, 250, 123)">Image</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        painter </span><span class="token operator">=</span><span class="token plain"> </span><span class="token function" style="color:rgb(80, 250, 123)">painterResource</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">Res</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">drawable</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">btn_android_id_rec</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        contentDescription </span><span class="token operator">=</span><span class="token plain"> </span><span class="token string-literal singleline string" style="color:rgb(255, 121, 198)">"Continue with Google"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        contentScale </span><span class="token operator">=</span><span class="token plain"> ContentScale</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">FillWidth</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        modifier </span><span class="token operator">=</span><span class="token plain"> Modifier</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">fillMaxWidth</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token number">5f</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">            </span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">clickable</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">                scope</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">launch</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">                    </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">if</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">nonce </span><span class="token operator">==</span><span class="token plain"> Defaults</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">default</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">return</span><span class="token label symbol" style="color:rgb(248, 248, 242)">@launch</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">                    loaderState </span><span class="token operator">=</span><span class="token plain"> </span><span class="token boolean">true</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">                    authProvider</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">signIn</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">nonce</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">                        </span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">onSuccess</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"> token </span><span class="token operator">-&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">                            </span><span class="token function" style="color:rgb(80, 250, 123)">handleReceivedGoogleTokenId</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">token</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">                        </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">                        </span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">onFailure</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"> exception </span><span class="token operator">-&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">                            </span><span class="token comment" style="color:rgb(98, 114, 164)">// TODO: Handle error properly</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">                            </span><span class="token function" style="color:rgb(80, 250, 123)">println</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token string-literal singleline string" style="color:rgb(255, 121, 198)">"Sign-in failed: </span><span class="token string-literal singleline interpolation interpolation-punctuation punctuation" style="color:rgb(248, 248, 242)">${</span><span class="token string-literal singleline interpolation expression">exception</span><span class="token string-literal singleline interpolation expression punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token string-literal singleline interpolation expression">message</span><span class="token string-literal singleline interpolation interpolation-punctuation punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token string-literal singleline string" style="color:rgb(255, 121, 198)">"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">                        </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">                    loaderState </span><span class="token operator">=</span><span class="token plain"> </span><span class="token boolean">false</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">                </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">            </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><br></span></code></pre></div></div>
<p>So what exactly is this? This is a composable function in which we define <code>ClickableContinueWithGoogle</code> which has two ways to trigger a sign in. Our automated implementation triggers in a <code>LaunchdedEffect</code> and a modifier with clickable property. Both these use methods from <code>rememberGoogleAuthProvider()</code> - an expect implementation which we explore next.</p>
<h3 class="anchor anchorTargetStickyNavbar_moQH" id="expect-implementation-for-remembergoogleauthprovider">expect implementation for <code>rememberGoogleAuthProvider</code><a href="https://docs.alwinsden.com/articles/kmp-gauth-multiplatform#expect-implementation-for-remembergoogleauthprovider" class="hash-link" aria-label="Direct link to expect-implementation-for-remembergoogleauthprovider" title="Direct link to expect-implementation-for-remembergoogleauthprovider" translate="no">​</a></h3>
<p>refer: <a href="https://github.com/alwinsDen/synapse-ai/blob/master/composeApp/src/commonMain/kotlin/com/alwinsden/dino/authentication/components/GoogleAuthProvider.kt" target="_blank" rel="noopener noreferrer" class="">GoogleAuthProvider.kt</a></p>
<div class="language-kotlin codeBlockContainer_swyL theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_Lz3e"><pre tabindex="0" class="prism-code language-kotlin codeBlock_g3dV thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_zDA_"><span class="token-line" style="color:#F8F8F2"><span class="token comment" style="color:rgb(98, 114, 164)">/**</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token comment" style="color:rgb(98, 114, 164)"> * Interface for Google authentication functionality across platforms.</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token comment" style="color:rgb(98, 114, 164)"> * Provides a common abstraction for Google Sign-In operations.</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token comment" style="color:rgb(98, 114, 164)"> */</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">interface</span><span class="token plain"> GoogleAuthProvider </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token comment" style="color:rgb(98, 114, 164)">/**</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token comment" style="color:rgb(98, 114, 164)">     * Initiates the sign-in flow with the provided nonce.</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token comment" style="color:rgb(98, 114, 164)">     *</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token comment" style="color:rgb(98, 114, 164)">     * @param nonce The nonce value from the server for token validation</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token comment" style="color:rgb(98, 114, 164)">     * @return Result containing the Google ID token on success, or an error</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token comment" style="color:rgb(98, 114, 164)">     */</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">suspend</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">fun</span><span class="token plain"> </span><span class="token function" style="color:rgb(80, 250, 123)">signIn</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">nonce</span><span class="token operator">:</span><span class="token plain"> String</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token operator">:</span><span class="token plain"> Result</span><span class="token operator">&lt;</span><span class="token plain">String</span><span class="token operator">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token comment" style="color:rgb(98, 114, 164)">/**</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token comment" style="color:rgb(98, 114, 164)">     * Checks for existing credentials without prompting the user.</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token comment" style="color:rgb(98, 114, 164)">     * Useful for automatic sign-in on app launch.</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token comment" style="color:rgb(98, 114, 164)">     *</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token comment" style="color:rgb(98, 114, 164)">     * @return The existing Google ID token if available, null otherwise</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token comment" style="color:rgb(98, 114, 164)">     */</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">suspend</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">fun</span><span class="token plain"> </span><span class="token function" style="color:rgb(80, 250, 123)">checkExistingCredentials</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">nonce</span><span class="token operator">:</span><span class="token plain"> String</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token operator">:</span><span class="token plain"> String</span><span class="token operator">?</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token comment" style="color:rgb(98, 114, 164)">/**</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token comment" style="color:rgb(98, 114, 164)"> * Platform-specific factory function to create a GoogleAuthProvider instance.</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token comment" style="color:rgb(98, 114, 164)"> * Each platform provides its own implementation.</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token comment" style="color:rgb(98, 114, 164)"> */</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token annotation builtin" style="color:rgb(189, 147, 249)">@Composable</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">expect</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">fun</span><span class="token plain"> </span><span class="token function" style="color:rgb(80, 250, 123)">rememberGoogleAuthProvider</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token operator">:</span><span class="token plain"> GoogleAuthProvider</span><br></span></code></pre></div></div>
<p>This expect composable has an actual implementation for each Android &amp; iOS. This defines an <em>interface</em> on how the returned class properties need to be structured.</p>
<p>Since we are defining actual functions to be platform specific, we need to use native libraries.</p>
<p>For Android, we install Google credentials libs in <code>androidMain/build.gradle.kts</code> file:</p>
<div class="language-kotlin codeBlockContainer_swyL theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_Lz3e"><pre tabindex="0" class="prism-code language-kotlin codeBlock_g3dV thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_zDA_"><span class="token-line" style="color:#F8F8F2"><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">val</span><span class="token plain"> credentialVersion </span><span class="token operator">=</span><span class="token plain"> </span><span class="token string-literal singleline string" style="color:rgb(255, 121, 198)">"1.6.0-rc01"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token function" style="color:rgb(80, 250, 123)">implementation</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token string-literal singleline string" style="color:rgb(255, 121, 198)">"androidx.credentials:credentials:</span><span class="token string-literal singleline interpolation interpolation-punctuation punctuation" style="color:rgb(248, 248, 242)">$</span><span class="token string-literal singleline interpolation expression">credentialVersion</span><span class="token string-literal singleline string" style="color:rgb(255, 121, 198)">"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token function" style="color:rgb(80, 250, 123)">implementation</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token string-literal singleline string" style="color:rgb(255, 121, 198)">"androidx.credentials:credentials-play-services-auth:</span><span class="token string-literal singleline interpolation interpolation-punctuation punctuation" style="color:rgb(248, 248, 242)">$</span><span class="token string-literal singleline interpolation expression">credentialVersion</span><span class="token string-literal singleline string" style="color:rgb(255, 121, 198)">"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token function" style="color:rgb(80, 250, 123)">implementation</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token string-literal singleline string" style="color:rgb(255, 121, 198)">"com.google.android.libraries.identity.googleid:googleid:1.1.1"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><br></span></code></pre></div></div>
<h3 class="anchor anchorTargetStickyNavbar_moQH" id="android-actual-implementation">Android actual implementation<a href="https://docs.alwinsden.com/articles/kmp-gauth-multiplatform#android-actual-implementation" class="hash-link" aria-label="Direct link to Android actual implementation" title="Direct link to Android actual implementation" translate="no">​</a></h3>
<p>refer: <a href="https://github.com/alwinsDen/synapse-ai/blob/master/composeApp/src/androidMain/kotlin/com/alwinsden/dino/authentication/components/GoogleAuthProvider.android.kt" target="_blank" rel="noopener noreferrer" class="">GoogleAuthProvider.android.kt</a></p>
<div class="language-kotlin codeBlockContainer_swyL theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_Lz3e"><pre tabindex="0" class="prism-code language-kotlin codeBlock_g3dV thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_zDA_"><span class="token-line" style="color:#F8F8F2"><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">import</span><span class="token plain"> android</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">content</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">Context</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">import</span><span class="token plain"> android</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">util</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">Log</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">import</span><span class="token plain"> androidx</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">compose</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">runtime</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">Composable</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">import</span><span class="token plain"> androidx</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">compose</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">runtime</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">remember</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">import</span><span class="token plain"> androidx</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">compose</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">ui</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">platform</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">LocalContext</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">import</span><span class="token plain"> androidx</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">credentials</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token operator">*</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">import</span><span class="token plain"> androidx</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">credentials</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">exceptions</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">GetCredentialException</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">import</span><span class="token plain"> com</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">alwinsden</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">dino</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">BuildKonfig</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">import</span><span class="token plain"> com</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">google</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">android</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">libraries</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">identity</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">googleid</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">GetGoogleIdOption</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">import</span><span class="token plain"> com</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">google</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">android</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">libraries</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">identity</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">googleid</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">GetSignInWithGoogleOption</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">import</span><span class="token plain"> com</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">google</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">android</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">libraries</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">identity</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">googleid</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">GoogleIdTokenCredential</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">import</span><span class="token plain"> com</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">google</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">android</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">libraries</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">identity</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">googleid</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">GoogleIdTokenParsingException</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token annotation builtin" style="color:rgb(189, 147, 249)">@Composable</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">actual</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">fun</span><span class="token plain"> </span><span class="token function" style="color:rgb(80, 250, 123)">rememberGoogleAuthProvider</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token operator">:</span><span class="token plain"> GoogleAuthProvider </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">val</span><span class="token plain"> context </span><span class="token operator">=</span><span class="token plain"> LocalContext</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">current</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">return</span><span class="token plain"> remember </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token function" style="color:rgb(80, 250, 123)">AndroidGoogleAuthProvider</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">            context </span><span class="token operator">=</span><span class="token plain"> context</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">            credentialManager </span><span class="token operator">=</span><span class="token plain"> CredentialManager</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">create</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">context</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><br></span></code></pre></div></div>
<h4 class="anchor anchorTargetStickyNavbar_moQH" id="suspended-signin-function">Suspended signIn function<a href="https://docs.alwinsden.com/articles/kmp-gauth-multiplatform#suspended-signin-function" class="hash-link" aria-label="Direct link to Suspended signIn function" title="Direct link to Suspended signIn function" translate="no">​</a></h4>
<p>refer: <a href="https://github.com/alwinsDen/synapse-ai/blob/master/composeApp/src/androidMain/kotlin/com/alwinsden/dino/authentication/components/GoogleAuthProvider.android.kt" target="_blank" rel="noopener noreferrer" class="">GoogleAuthProvider.android.kt</a></p>
<div class="language-kotlin codeBlockContainer_swyL theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_Lz3e"><pre tabindex="0" class="prism-code language-kotlin codeBlock_g3dV thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_zDA_"><span class="token-line" style="color:#F8F8F2"><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">override</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">suspend</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">fun</span><span class="token plain"> </span><span class="token function" style="color:rgb(80, 250, 123)">signIn</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">nonce</span><span class="token operator">:</span><span class="token plain"> String</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token operator">:</span><span class="token plain"> Result</span><span class="token operator">&lt;</span><span class="token plain">String</span><span class="token operator">&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">return</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">try</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">val</span><span class="token plain"> signInWithGoogleOption </span><span class="token operator">=</span><span class="token plain"> GetSignInWithGoogleOption</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">Builder</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">            serverClientId </span><span class="token operator">=</span><span class="token plain"> BuildKonfig</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">CLIENT_ID_GOOGLE_AUTH</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">            </span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">setNonce</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">nonce</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">            </span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">build</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">val</span><span class="token plain"> request </span><span class="token operator">=</span><span class="token plain"> GetCredentialRequest</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">Builder</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">            </span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">addCredentialOption</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">signInWithGoogleOption</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">            </span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">build</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">val</span><span class="token plain"> result </span><span class="token operator">=</span><span class="token plain"> credentialManager</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">getCredential</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">            request </span><span class="token operator">=</span><span class="token plain"> request</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">            context </span><span class="token operator">=</span><span class="token plain"> context</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        Log</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">i</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">TAG</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token string-literal singleline string" style="color:rgb(255, 121, 198)">"Manual Google Sign-in success"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token function" style="color:rgb(80, 250, 123)">extractGoogleIdToken</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">result</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">catch</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">e</span><span class="token operator">:</span><span class="token plain"> GetCredentialException</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        Log</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">e</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">TAG</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token string-literal singleline string" style="color:rgb(255, 121, 198)">"Error getting credential"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> e</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        Result</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">failure</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">e</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><br></span></code></pre></div></div>
<p>Here BuildKonfig is a generated object created by a popular Kotlin Multiplatform (KMP) Gradle plugin called <a href="https://github.com/yshrsmz/BuildKonfig" target="_blank" rel="noopener noreferrer" class="">BuildKonfig</a>. It injects the Google console auth key from <code>secrets.properties</code> file. more <a href="https://github.com/alwinsDen/synapse-ai/tree/master/composeApp/build.gradle.kts#L100" target="_blank" rel="noopener noreferrer" class="">here</a>.</p>
<h3 class="anchor anchorTargetStickyNavbar_moQH" id="what-is-nonce-here">What is Nonce here?<a href="https://docs.alwinsden.com/articles/kmp-gauth-multiplatform#what-is-nonce-here" class="hash-link" aria-label="Direct link to What is Nonce here?" title="Direct link to What is Nonce here?" translate="no">​</a></h3>
<p>This is a safety mechanism in place to prevent replay attacks. Nonce flows from the server, usually a JWT token.</p>
<p><em>Valkey implementation:</em> <a href="https://github.com/alwinsDen/synapse-ai/blob/master/server/src/main/kotlin/com/alwinsden/dino/valkeyManager/glideInitiator.kt" target="_blank" rel="noopener noreferrer" class="">Valkey Glide</a></p>
<div class="language-shell codeBlockContainer_swyL theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_Lz3e"><pre tabindex="0" class="prism-code language-shell codeBlock_g3dV thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_zDA_"><span class="token-line" style="color:#F8F8F2"><span class="token plain">| Backend System                              |</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">|---------------------------------------------|</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">| 1. Generate Secure Nonce                    |</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">|    &amp; Save to Valkey/Redis                   |</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">|               |                             |</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">|               v                             |</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">| 2. Share Nonce with CLI/Client              |</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">|               |                             |</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">|---------------|-----------------------------|</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">                |</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">                v</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">| CLI / Client Application                    |</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">|---------------------------------------------|</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">| 3. Init GAuth Builder (setNonce)            |</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">|               |                             |</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">|               v                             |</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">| 4. Perform Google Sign-In                   |</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">|    (Result: Encrypted Token ID w/ Nonce)    |</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">|               |                             |</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">|               v                             |</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">| 5. Send Token ID to Backend                 |</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">|               |                             |</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">|---------------|-----------------------------|</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">                |</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">                v</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">| Backend System                              |</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">|---------------------------------------------|</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">| 6. Verify Google Token Signature            |</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">|               |                             |</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">|               v                             |</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">| 7. Extract Nonce &amp; Check Valkey/Redis       |</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">|               |                             |</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">|    [  Exists &amp; Matches?  ]                  |</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">|       | Yes           | No                  |</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">|       |               +----&gt; | Reject |     |</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">|       v                                     |</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">| 8. Generate Custom App JWT                  |</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">|               |                             |</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">|               v                             |</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">| 9. Return JWT to CLI (Login Success)        |</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">|_____________________________________________|</span><br></span></code></pre></div></div>
<h4 class="anchor anchorTargetStickyNavbar_moQH" id="suspended-checkexistingcredentials-function">Suspended checkExistingCredentials function<a href="https://docs.alwinsden.com/articles/kmp-gauth-multiplatform#suspended-checkexistingcredentials-function" class="hash-link" aria-label="Direct link to Suspended checkExistingCredentials function" title="Direct link to Suspended checkExistingCredentials function" translate="no">​</a></h4>
<div class="language-kotlin codeBlockContainer_swyL theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_Lz3e"><pre tabindex="0" class="prism-code language-kotlin codeBlock_g3dV thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_zDA_"><span class="token-line" style="color:#F8F8F2"><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">override</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">suspend</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">fun</span><span class="token plain"> </span><span class="token function" style="color:rgb(80, 250, 123)">checkExistingCredentials</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">nonce</span><span class="token operator">:</span><span class="token plain"> String</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token operator">:</span><span class="token plain"> String</span><span class="token operator">?</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">return</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">try</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">val</span><span class="token plain"> googleIdOption </span><span class="token operator">=</span><span class="token plain"> GetGoogleIdOption</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">Builder</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">            </span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">setFilterByAuthorizedAccounts</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token boolean">true</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">            </span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">setAutoSelectEnabled</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token boolean">true</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">            </span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">setServerClientId</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">BuildKonfig</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">CLIENT_ID_GOOGLE_AUTH</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">            </span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">setNonce</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">nonce</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">            </span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">build</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">val</span><span class="token plain"> request </span><span class="token operator">=</span><span class="token plain"> GetCredentialRequest</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">Builder</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">            </span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">addCredentialOption</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">googleIdOption</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">            </span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">build</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">val</span><span class="token plain"> result </span><span class="token operator">=</span><span class="token plain"> credentialManager</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">getCredential</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">            request </span><span class="token operator">=</span><span class="token plain"> request</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">            context </span><span class="token operator">=</span><span class="token plain"> context</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        Log</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">i</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">TAG</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token string-literal singleline string" style="color:rgb(255, 121, 198)">"Auto Google Sign-in success"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token function" style="color:rgb(80, 250, 123)">extractGoogleIdToken</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">result</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">getOrNull</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">catch</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">e</span><span class="token operator">:</span><span class="token plain"> GetCredentialException</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        Log</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">d</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">TAG</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token string-literal singleline string" style="color:rgb(255, 121, 198)">"No existing credentials found"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> e</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">null</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><br></span></code></pre></div></div>
<p>In either case, the returned Google token ID, serves the same primary function.</p>
<p>This expect function also has a corresponding implementation in iOS which requires a more complex setup and will be discussed in an upcoming article. Until then check the code <a href="https://github.com/alwinsDen/synapse-ai/tree/master/shared/src/iosMain/kotlin/authManager/ClickTriggerAuth.kt" target="_blank" rel="noopener noreferrer" class="">here</a>.</p>
<div class="theme-admonition theme-admonition-success admonition_Yu28 alert alert--success"><div class="admonitionHeading_pWiJ"><span class="admonitionIcon_TSs0"><svg viewBox="0 0 12 16"><path fill-rule="evenodd" d="M6.5 0C3.48 0 1 2.19 1 5c0 .92.55 2.25 1 3 1.34 2.25 1.78 2.78 2 4v1h5v-1c.22-1.22.66-1.75 2-4 .45-.75 1-2.08 1-3 0-2.81-2.48-5-5.5-5zm3.64 7.48c-.25.44-.47.8-.67 1.11-.86 1.41-1.25 2.06-1.45 3.23-.02.05-.02.11-.02.17H5c0-.06 0-.13-.02-.17-.2-1.17-.59-1.83-1.45-3.23-.2-.31-.42-.67-.67-1.11C2.44 6.78 2 5.65 2 5c0-2.2 2.02-4 4.5-4 1.22 0 2.36.42 3.22 1.19C10.55 2.94 11 3.94 11 5c0 .66-.44 1.78-.86 2.48zM4 14h5c-.23 1.14-1.3 2-2.5 2s-2.27-.86-2.5-2z"></path></svg></span>success</div><div class="admonitionContent_Qh44"><p>This is my first article on KMP, which I too am new to. If you have any feedback or suggestions, please feel free to reach out to me.
Until then, consider starring the <a href="https://github.com/alwinsDen/synapse-ai" target="_blank" rel="noopener noreferrer" class="">project</a> and follow me on <a href="https://github.com/alwinsDen" target="_blank" rel="noopener noreferrer" class="">GitHub</a>.</p></div></div>]]></content>
        <author>
            <name>Alwin T Varghese</name>
            <uri>https://alwinsden.com</uri>
        </author>
        <category label="kotlin" term="kotlin"/>
        <category label="mutiplatform" term="mutiplatform"/>
        <category label="android" term="android"/>
        <category label="synapse" term="synapse"/>
    </entry>
</feed>