<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Ashish Tandon</title>
    <description>The latest articles on DEV Community by Ashish Tandon (@_ashish_tandon_).</description>
    <link>https://dev.to/_ashish_tandon_</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3815750%2F7a113fd3-39e8-402d-a340-2e811dccce85.png</url>
      <title>DEV Community: Ashish Tandon</title>
      <link>https://dev.to/_ashish_tandon_</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/_ashish_tandon_"/>
    <language>en</language>
    <item>
      <title>Constraints in Flutter: The One Concept That Changes Everything</title>
      <dc:creator>Ashish Tandon</dc:creator>
      <pubDate>Wed, 08 Apr 2026 09:29:21 +0000</pubDate>
      <link>https://dev.to/_ashish_tandon_/constraints-in-flutter-the-one-concept-that-changes-everything-5af0</link>
      <guid>https://dev.to/_ashish_tandon_/constraints-in-flutter-the-one-concept-that-changes-everything-5af0</guid>
      <description>&lt;p&gt;Flutter layout starts feeling predictable once you understand one core idea.&lt;/p&gt;

&lt;p&gt;Most UI issues—unexpected sizes, overflow errors, or widgets not behaving as expected—are usually not random. In most cases, they come down to a single concept:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;constraints.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The Golden Rule of Flutter Layout
&lt;/h2&gt;

&lt;p&gt;If you remember only one thing about Flutter layout, remember this:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Constraints go down. Sizes go up. Parent sets position.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This simple rule explains how every widget in Flutter is laid out. Once this clicks, many confusing behaviors start making sense.&lt;/p&gt;




&lt;h2&gt;
  
  
  How Layout Actually Works
&lt;/h2&gt;

&lt;p&gt;Flutter layout is a step-by-step process between parent and child widgets. Each phase has a clear responsibility.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Constraints go down
&lt;/h3&gt;

&lt;p&gt;The parent widget tells the child what it is allowed to do. It defines a range using minimum and maximum width and height.&lt;/p&gt;

&lt;p&gt;In simple terms:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“You must be at least this big, but no bigger than this.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This means a child never has complete freedom—it always operates within limits set by its parent.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Sizes go up
&lt;/h3&gt;

&lt;p&gt;After receiving constraints, the child decides its size within those limits.&lt;/p&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Given your rules, I’ll be 100×100.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;A few important points:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The child &lt;strong&gt;cannot exceed the constraints&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;It must choose a size &lt;strong&gt;within the allowed range&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  3. Parent sets position
&lt;/h3&gt;

&lt;p&gt;Once the child reports its size, the parent decides where to place it.&lt;/p&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“I’ll place you at (x: 0, y: 20).”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So layout is not just about size—it also includes positioning, which is always controlled by the parent.&lt;/p&gt;




&lt;h2&gt;
  
  
  Tight vs Loose Constraints
&lt;/h2&gt;

&lt;p&gt;Understanding this distinction makes many layout behaviors much clearer.&lt;/p&gt;

&lt;h3&gt;
  
  
  Tight Constraints
&lt;/h3&gt;

&lt;p&gt;In tight constraints, the parent gives an exact size.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“You must be exactly this size.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This means:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The child has &lt;strong&gt;no flexibility&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;It must strictly follow the given dimensions&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Loose Constraints
&lt;/h3&gt;

&lt;p&gt;In loose constraints, the parent provides a range instead of a fixed size.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“You can be any size up to this limit.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This allows:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The child to choose a smaller size if needed
&lt;/li&gt;
&lt;li&gt;But it still cannot exceed the maximum limit
&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Why This Matters
&lt;/h2&gt;

&lt;p&gt;Once you understand constraints, layout stops feeling unpredictable.&lt;/p&gt;

&lt;p&gt;You no longer rely on trial and error. Instead, you can reason about what is happening.&lt;/p&gt;

&lt;p&gt;For example, instead of asking:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Why is this widget behaving like this?”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;You start asking:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“What constraints is it receiving?”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That shift in thinking makes debugging much easier and more systematic.&lt;/p&gt;




&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Flutter layout is not about manually controlling sizes.&lt;/p&gt;

&lt;p&gt;It is about understanding how constraints flow through the widget tree.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Constraints go down. Sizes go up. Parent sets position.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Once you internalize this, many common layout issues become easier to understand—and easier to fix.&lt;/p&gt;

</description>
      <category>flutter</category>
      <category>ui</category>
      <category>dart</category>
      <category>mobile</category>
    </item>
    <item>
      <title>Flutter Google Sign-In with google_sign_in 7: Understanding the New Authentication Flow</title>
      <dc:creator>Ashish Tandon</dc:creator>
      <pubDate>Tue, 10 Mar 2026 02:29:28 +0000</pubDate>
      <link>https://dev.to/_ashish_tandon_/flutter-google-sign-in-with-googlesignin-7-understanding-the-new-authentication-flow-2pbe</link>
      <guid>https://dev.to/_ashish_tandon_/flutter-google-sign-in-with-googlesignin-7-understanding-the-new-authentication-flow-2pbe</guid>
      <description>&lt;p&gt;Starting with &lt;code&gt;google_sign_in ^7.0.0&lt;/code&gt;, the plugin underwent a major refactor to support the Android Credential Manager and modern Google Identity Services. This introduced several breaking changes that move away from the traditional “all-in-one” &lt;code&gt;signIn()&lt;/code&gt; method.&lt;/p&gt;

&lt;p&gt;If you recently upgraded your Flutter project, you may suddenly encounter multiple compilation errors or unexpected behavior.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Common issues include:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;GoogleSignIn()&lt;/code&gt; constructor no longer exists&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;signIn()&lt;/code&gt; method is removed&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;accessToken&lt;/code&gt; missing from &lt;code&gt;GoogleSignInAuthentication&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Account picker not appearing unless &lt;code&gt;initialize()&lt;/code&gt; is called&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These changes can be confusing at first, but they come from an architectural shift where authentication and authorization are now handled separately.&lt;/p&gt;

&lt;p&gt;Let’s go through the changes and how to fix them.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Fix 1 — GoogleSignIn Constructor Removed (Singleton Pattern)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;GoogleSignIn&lt;/code&gt; class no longer allows you to create new instances using &lt;code&gt;GoogleSignIn()&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;To ensure compatibility with the system-level Credential Manager sheet, the plugin now uses a singleton pattern.&lt;/p&gt;

&lt;p&gt;Replace your constructor call with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;googleSignIn&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;GoogleSignIn&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;instance&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Fix 2 — Initialization Is Now Mandatory&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In previous versions, initialization happened implicitly.&lt;br&gt;
Starting with v7.0.0, you must call and await the &lt;code&gt;initialize()&lt;/code&gt; method exactly once before using the plugin.&lt;/p&gt;

&lt;p&gt;Call this during app startup (for example in main() or your authentication service initialization):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;GoogleSignIn&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;instance&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;initialize&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If initialization is skipped, the authentication sheet may not appear.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Fix 3 — signIn() Replaced by authenticate()&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The familiar &lt;code&gt;signIn()&lt;/code&gt; method has been replaced by &lt;code&gt;authenticate()&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;This method triggers the new system-level account picker / Credential Manager sheet on supported Android versions.&lt;/p&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;GoogleSignInAccount&lt;/span&gt; &lt;span class="n"&gt;googleUser&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;GoogleSignIn&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;instance&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;authenticate&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Fix 4 — accessToken Missing (Authentication vs Authorization)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This is the biggest architectural change in &lt;code&gt;google_sign_in 7&lt;/code&gt;. Google has separated authentication (who the user is) from authorization (what permissions the app has).&lt;/p&gt;

&lt;p&gt;After calling &lt;code&gt;authenticate()&lt;/code&gt;, you can still obtain the idToken from &lt;code&gt;googleUser.authentication&lt;/code&gt;. However, the accessToken is no longer returned automatically. To retrieve it, you must explicitly request scopes using the &lt;code&gt;authorizationClient&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;  &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;clientAuth&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
      &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;googleUser&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;authorizationClient&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;authorizeScopes&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="s"&gt;'email'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;'profile'&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Complete google_sign_in 7.0.0+ Implementation
&lt;/h2&gt;

&lt;p&gt;If you need both tokens (for example when integrating with Firebase or other APIs), the following pattern works:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="n"&gt;Future&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;UserCredential&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;signInWithGoogle&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="kd"&gt;async&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// 1. Ensure initialization&lt;/span&gt;
  &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;googleSignIn&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;GoogleSignIn&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;instance&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="c1"&gt;// 2. Authentication (Identity)&lt;/span&gt;
  &lt;span class="c1"&gt;// Triggers the account picker / Credential Manager sheet&lt;/span&gt;
  &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;GoogleSignInAccount&lt;/span&gt; &lt;span class="n"&gt;googleUser&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
      &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;googleSignIn&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;authenticate&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

  &lt;span class="c1"&gt;// 3. Authorization (Permissions)&lt;/span&gt;
  &lt;span class="c1"&gt;// Request scopes to retrieve the Access Token&lt;/span&gt;
  &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="kt"&gt;List&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;scopes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;'email'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;'profile'&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
  &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;clientAuth&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
      &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;googleUser&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;authorizationClient&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;authorizeScopes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;scopes&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="c1"&gt;// 4. Create Firebase Credential&lt;/span&gt;
  &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;credential&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;GoogleAuthProvider&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;credential&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nl"&gt;idToken:&lt;/span&gt; &lt;span class="n"&gt;googleUser&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;authentication&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;idToken&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nl"&gt;accessToken:&lt;/span&gt; &lt;span class="n"&gt;clientAuth&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;accessToken&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="c1"&gt;// 5. Sign in to Firebase&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;FirebaseAuth&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;instance&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;signInWithCredential&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;credential&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;IMPORTANT:&lt;/strong&gt; Make sure &lt;code&gt;GoogleSignIn.instance.initialize()&lt;/code&gt; is called once during app startup before invoking &lt;code&gt;signInWithGoogle()&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Final Thoughts&lt;/strong&gt;&lt;br&gt;
If you're upgrading from older versions of &lt;code&gt;google_sign_in&lt;/code&gt;, these changes can feel confusing at first because many familiar APIs were removed or redesigned.&lt;/p&gt;

&lt;p&gt;However, once you understand the separation between authentication and authorization, the new API flow becomes much clearer and aligns better with modern identity systems.&lt;/p&gt;

&lt;p&gt;Hopefully this saves someone else the debugging time.&lt;/p&gt;

</description>
      <category>flutter</category>
      <category>googlesignin</category>
      <category>firebase</category>
    </item>
  </channel>
</rss>
