<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Flutter and Dart: from fundamentals to production on Ivaldo de Oliveira Batista Júnior</title><link>https://ivaldo.eti.br/learn/flutter-dart/</link><description>Recent content in Flutter and Dart: from fundamentals to production on Ivaldo de Oliveira Batista Júnior</description><generator>Hugo</generator><language>en</language><copyright>© 2026 Ivaldo de Oliveira Batista Júnior</copyright><atom:link href="https://ivaldo.eti.br/learn/flutter-dart/index.xml" rel="self" type="application/rss+xml"/><item><title>Flutter fundamentals for .NET developers</title><link>https://ivaldo.eti.br/learn/flutter-dart/flutter-fundamentals/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://ivaldo.eti.br/learn/flutter-dart/flutter-fundamentals/</guid><description>&lt;h2 id="what-you-will-build"&gt;What you will build&lt;/h2&gt;
&lt;p&gt;You &lt;strong&gt;do not need to know how to create a Flutter page before starting&lt;/strong&gt;. This module builds one with you, one small piece at a time. By the end, you will have a &lt;code&gt;developer_profile&lt;/code&gt; project with:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;an application configured with &lt;code&gt;MaterialApp&lt;/code&gt; and &lt;code&gt;ThemeData&lt;/code&gt;;&lt;/li&gt;
&lt;li&gt;a &lt;code&gt;DeveloperProfilePage&lt;/code&gt; in its own file;&lt;/li&gt;
&lt;li&gt;a name, specialty, location, and contact button;&lt;/li&gt;
&lt;li&gt;a layout that remains usable in a narrow window;&lt;/li&gt;
&lt;li&gt;visible feedback when the button is pressed;&lt;/li&gt;
&lt;li&gt;an automated test and a README with run instructions.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Do not paste the entire final solution at once. Run the app at every &lt;strong&gt;checkpoint&lt;/strong&gt;. If something breaks, you will know which small change to inspect.&lt;/p&gt;</description></item><item><title>Modern Dart for C# developers</title><link>https://ivaldo.eti.br/learn/flutter-dart/modern-dart/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://ivaldo.eti.br/learn/flutter-dart/modern-dart/</guid><description>&lt;h2 id="dart-is-not-c-with-different-punctuation"&gt;Dart is not C# with different punctuation&lt;/h2&gt;
&lt;p&gt;Classes, interfaces, and &lt;code&gt;async/await&lt;/code&gt; feel familiar, but idiomatic Dart favors immutable data, named parameters, concise constructors, and explicit nullable types.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code class="language-dart" data-lang="dart"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;final&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;class&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;Product&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; Product({
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;required&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;this&lt;/span&gt;.id,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;required&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;this&lt;/span&gt;.name,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;required&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;this&lt;/span&gt;.price,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; });
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;final&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;String&lt;/span&gt; id;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;final&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;String&lt;/span&gt; name;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;final&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;double&lt;/span&gt; price;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;final&lt;/code&gt; prevents reassignment after initialization. &lt;code&gt;const&lt;/code&gt; creates compile-time values when the complete expression is constant. Immutability is a strong default because it limits intermediate states and makes widgets easier to reason about.&lt;/p&gt;</description></item><item><title>Flutter architecture for professional projects</title><link>https://ivaldo.eti.br/learn/flutter-dart/professional-architecture/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://ivaldo.eti.br/learn/flutter-dart/professional-architecture/</guid><description>&lt;h2 id="the-problem-architecture-should-solve"&gt;The problem architecture should solve&lt;/h2&gt;
&lt;p&gt;A small application can mix API access, validation, and UI updates in one widget. In a real product, that creates a fragile dependency chain. Architecture establishes a direction:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;presentation -&amp;gt; domain &amp;lt;- data
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ^
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; external
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The domain stays in the center and does not import Flutter, Dio, Firebase, or a database. External layers implement internal contracts and remain replaceable.&lt;/p&gt;
&lt;h2 id="feature-first-with-layers-inside"&gt;Feature-first, with layers inside&lt;/h2&gt;
&lt;p&gt;Group code that changes together:&lt;/p&gt;</description></item><item><title>Professional interfaces with Material 3</title><link>https://ivaldo.eti.br/learn/flutter-dart/professional-interfaces/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://ivaldo.eti.br/learn/flutter-dart/professional-interfaces/</guid><description>&lt;h2 id="a-professional-interface-is-a-system"&gt;A professional interface is a system&lt;/h2&gt;
&lt;p&gt;An isolated screen can look polished and still fall apart as the product grows. Professional interfaces need shared rules for spacing, typography, color, states, and responsive behavior.&lt;/p&gt;
&lt;p&gt;Material 3 supplies foundations and components, but it does not make product decisions for you. Keep those decisions in the theme:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code class="language-dart" data-lang="dart"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;ThemeData buildTheme(ColorScheme colors) &lt;span style="color:#f92672"&gt;=&amp;gt;&lt;/span&gt; ThemeData(
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; useMaterial3: &lt;span style="color:#66d9ef"&gt;true&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; colorScheme: colors,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; textTheme: &lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; TextTheme(
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; headlineMedium: TextStyle(fontWeight: FontWeight.w700),
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; bodyLarge: TextStyle(fontSize: &lt;span style="color:#ae81ff"&gt;16&lt;/span&gt;, height: &lt;span style="color:#ae81ff"&gt;1.5&lt;/span&gt;),
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ),
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; inputDecorationTheme: &lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; InputDecorationTheme(
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; border: OutlineInputBorder(),
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ),
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Avoid arbitrary colors and sizes inside widgets. A theme enables consistency, dark mode, and safer brand changes.&lt;/p&gt;</description></item><item><title>State management with Provider and Riverpod</title><link>https://ivaldo.eti.br/learn/flutter-dart/state-management/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://ivaldo.eti.br/learn/flutter-dart/state-management/</guid><description>&lt;h2 id="state-is-information-over-time"&gt;State is information over time&lt;/h2&gt;
&lt;p&gt;Form fields, authenticated sessions, filters, remote data, and failures have different lifecycles. Before choosing a library, ask who owns the state, who observes it, whether it survives navigation, and whether it is a source value or a derivation.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;setState&lt;/code&gt; is appropriate for short-lived local state. Trouble begins when distant widgets depend on the same value or asynchronous effects are triggered from &lt;code&gt;build&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id="provider-and-changenotifier"&gt;Provider and ChangeNotifier&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code class="language-dart" data-lang="dart"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;final&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;class&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;CounterController&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;extends&lt;/span&gt; ChangeNotifier {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; _value &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;get&lt;/span&gt; value &lt;span style="color:#f92672"&gt;=&amp;gt;&lt;/span&gt; _value;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; increment() {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; _value&lt;span style="color:#f92672"&gt;++&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; notifyListeners();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code class="language-dart" data-lang="dart"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;ChangeNotifierProvider(
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; create: (_) &lt;span style="color:#f92672"&gt;=&amp;gt;&lt;/span&gt; CounterController(),
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; child: &lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; CounterPage(),
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Keep controllers focused, do not expose mutable collections, and avoid notifications for changes the UI does not use. ChangeNotifier is approachable, but large models can accumulate implicit dependencies and broad rebuilds.&lt;/p&gt;</description></item><item><title>REST APIs with Dio and production architecture</title><link>https://ivaldo.eti.br/learn/flutter-dart/rest-apis/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://ivaldo.eti.br/learn/flutter-dart/rest-apis/</guid><description>&lt;h2 id="integration-is-a-boundary"&gt;Integration is a boundary&lt;/h2&gt;
&lt;p&gt;An external API should not dictate the domain or leak transport details into the UI.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Widget -&amp;gt; Controller -&amp;gt; Use case -&amp;gt; Repository -&amp;gt; Data source -&amp;gt; HTTP
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The return path translates JSON into a DTO, the DTO into an entity, and exceptions into known failures.&lt;/p&gt;
&lt;h2 id="centralize-dio-configuration"&gt;Centralize Dio configuration&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code class="language-dart" data-lang="dart"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Dio buildDio(AppEnvironment environment) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; Dio(
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; BaseOptions(
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; baseUrl: environment.apiUrl,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; connectTimeout: &lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; Duration(seconds: &lt;span style="color:#ae81ff"&gt;10&lt;/span&gt;),
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; receiveTimeout: &lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; Duration(seconds: &lt;span style="color:#ae81ff"&gt;20&lt;/span&gt;),
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; sendTimeout: &lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; Duration(seconds: &lt;span style="color:#ae81ff"&gt;20&lt;/span&gt;),
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; headers: &lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; {&lt;span style="color:#e6db74"&gt;&amp;#39;Accept&amp;#39;&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;application/json&amp;#39;&lt;/span&gt;},
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ),
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; );
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Do not create a client for every request. A shared instance supports consistent interceptors, cancellation, metrics, and policy.&lt;/p&gt;</description></item><item><title>Local persistence with SharedPreferences, Hive, and Drift</title><link>https://ivaldo.eti.br/learn/flutter-dart/local-persistence/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://ivaldo.eti.br/learn/flutter-dart/local-persistence/</guid><description>&lt;h2 id="persistence-changes-product-behavior"&gt;Persistence changes product behavior&lt;/h2&gt;
&lt;p&gt;Preferences, tokens, catalogs, and offline orders do not have the same requirements.&lt;/p&gt;
&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th&gt;Need&lt;/th&gt;
 &lt;th&gt;Typical option&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td&gt;Theme, language, simple flag&lt;/td&gt;
 &lt;td&gt;SharedPreferences&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;Object and key-value cache&lt;/td&gt;
 &lt;td&gt;Hive&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;Relations, filters, transactions&lt;/td&gt;
 &lt;td&gt;Drift/SQLite&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;Small secret&lt;/td&gt;
 &lt;td&gt;Platform secure storage&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Do not place sensitive tokens in regular preferences. Do not treat a cache as the only source of truth without an expiration policy.&lt;/p&gt;
&lt;h2 id="sharedpreferences-for-configuration"&gt;SharedPreferences for configuration&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code class="language-dart" data-lang="dart"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;final&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;class&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;PreferencesDataSource&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; PreferencesDataSource(&lt;span style="color:#66d9ef"&gt;this&lt;/span&gt;._preferences);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;final&lt;/span&gt; SharedPreferences _preferences;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;bool&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;get&lt;/span&gt; darkMode &lt;span style="color:#f92672"&gt;=&amp;gt;&lt;/span&gt; _preferences.getBool(&lt;span style="color:#e6db74"&gt;&amp;#39;darkMode&amp;#39;&lt;/span&gt;) &lt;span style="color:#f92672"&gt;??&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;false&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Future&lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;void&lt;/span&gt;&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; setDarkMode(&lt;span style="color:#66d9ef"&gt;bool&lt;/span&gt; enabled) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; _preferences.setBool(&lt;span style="color:#e6db74"&gt;&amp;#39;darkMode&amp;#39;&lt;/span&gt;, enabled);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Centralize keys and defaults. UI should talk to a controller or use case, not directly to a storage package.&lt;/p&gt;</description></item><item><title>Firebase for business applications</title><link>https://ivaldo.eti.br/learn/flutter-dart/firebase/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://ivaldo.eti.br/learn/flutter-dart/firebase/</guid><description>&lt;h2 id="backend-as-a-service-does-not-remove-architecture"&gt;Backend as a Service does not remove architecture&lt;/h2&gt;
&lt;p&gt;Firebase accelerates identity, real-time data, files, and push. The risk is allowing SDK calls to spread through widgets or treating login as authorization. Keep Firebase at the edge:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;presentation -&amp;gt; use cases -&amp;gt; repositories -&amp;gt; Firebase adapters
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Create separate projects for development, staging, and production. Client configuration identifies the project; administrative credentials and rules still require protection.&lt;/p&gt;
&lt;h2 id="authentication-and-session"&gt;Authentication and session&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code class="language-dart" data-lang="dart"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;abstract&lt;/span&gt; interface &lt;span style="color:#66d9ef"&gt;class&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;AuthRepository&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Stream&lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;AppUser&lt;span style="color:#f92672"&gt;?&amp;gt;&lt;/span&gt; authStateChanges();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Future&lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;AppUser&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; signInWithEmail(&lt;span style="color:#66d9ef"&gt;String&lt;/span&gt; email, &lt;span style="color:#66d9ef"&gt;String&lt;/span&gt; password);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Future&lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;void&lt;/span&gt;&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; signOut();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The implementation translates &lt;code&gt;FirebaseAuthException&lt;/code&gt; into application failures. Login messages should not disclose account existence when that creates an enumeration risk.&lt;/p&gt;</description></item><item><title>Testing, quality, and observability</title><link>https://ivaldo.eti.br/learn/flutter-dart/testing-observability/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://ivaldo.eti.br/learn/flutter-dart/testing-observability/</guid><description>&lt;h2 id="quality-is-layered-feedback"&gt;Quality is layered feedback&lt;/h2&gt;
&lt;p&gt;Tests do not prove that defects are absent; they reduce uncertainty around important behavior. A balanced strategy uses many fast domain tests, widget tests for user-visible behavior, and a small number of high-value integrated journeys.&lt;/p&gt;
&lt;h2 id="unit-tests"&gt;Unit tests&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code class="language-dart" data-lang="dart"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;test(&lt;span style="color:#e6db74"&gt;&amp;#39;applies a ten percent discount&amp;#39;&lt;/span&gt;, () {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; calculator &lt;span style="color:#f92672"&gt;=&lt;/span&gt; DiscountCalculator();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;final&lt;/span&gt; result &lt;span style="color:#f92672"&gt;=&lt;/span&gt; calculator.apply(total: &lt;span style="color:#ae81ff"&gt;100&lt;/span&gt;, percentage: &lt;span style="color:#ae81ff"&gt;10&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; expect(result, &lt;span style="color:#ae81ff"&gt;90&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;});
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Use Arrange, Act, and Assert, and name the behavior. A test should fail for one clear reason.&lt;/p&gt;</description></item><item><title>Release, CI/CD, and distribution</title><link>https://ivaldo.eti.br/learn/flutter-dart/release-cicd/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://ivaldo.eti.br/learn/flutter-dart/release-cicd/</guid><description>&lt;h2 id="delivery-is-part-of-the-product"&gt;Delivery is part of the product&lt;/h2&gt;
&lt;p&gt;An application is not finished when it compiles on a developer machine. A professional release must be reproducible, identifiable, signed, verified, and monitored.&lt;/p&gt;
&lt;h2 id="versioning-and-artifacts"&gt;Versioning and artifacts&lt;/h2&gt;
&lt;p&gt;In &lt;code&gt;pubspec.yaml&lt;/code&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;version&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;1.2.0+42&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The value before &lt;code&gt;+&lt;/code&gt; communicates the version to users; the build number identifies a store delivery. Generate artifacts from the exact revision that passed validation:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;flutter build appbundle --release
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;flutter build ipa --release
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;flutter build web --release
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;section class="command-explainer" aria-label="flutter build &amp;lt;target&amp;gt; --release"&gt;
 &lt;header class="command-explainer__header"&gt;
 &lt;span&gt;Artifact&lt;/span&gt;
 &lt;code&gt;flutter build &amp;lt;target&amp;gt; --release&lt;/code&gt;
 &lt;/header&gt;
 &lt;div class="command-explainer__body"&gt;
 &lt;p&gt;&lt;code&gt;build&lt;/code&gt; produces an artifact for the requested target; &lt;code&gt;--release&lt;/code&gt; selects optimizations and removes development tooling incompatible with distribution. The command neither publishes nor proves production behavior.&lt;/p&gt;</description></item><item><title>Capstone: Sales Management</title><link>https://ivaldo.eti.br/learn/flutter-dart/capstone/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://ivaldo.eti.br/learn/flutter-dart/capstone/</guid><description>&lt;h2 id="the-challenge"&gt;The challenge&lt;/h2&gt;
&lt;p&gt;Build &lt;strong&gt;Sales Management&lt;/strong&gt;, a business application for products, customers, and orders. The goal is not to reproduce one prescribed screen. It is to demonstrate that you can turn requirements into a cohesive, secure, operable solution.&lt;/p&gt;
&lt;p&gt;Continue from the foundation created throughout the modules. Commit in small increments and keep the application runnable at each milestone.&lt;/p&gt;
&lt;h2 id="functional-scope"&gt;Functional scope&lt;/h2&gt;
&lt;h3 id="identity-and-users"&gt;Identity and users&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Email sign-in and one social provider in the lab environment.&lt;/li&gt;
&lt;li&gt;Sign-out and safe session restoration.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;admin&lt;/code&gt;, &lt;code&gt;supervisor&lt;/code&gt;, and &lt;code&gt;seller&lt;/code&gt; profiles.&lt;/li&gt;
&lt;li&gt;Routes and actions also protected by backend rules.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="dashboard"&gt;Dashboard&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Total revenue, order count, active customers, and product count.&lt;/li&gt;
&lt;li&gt;Loading, empty, data, and failure states.&lt;/li&gt;
&lt;li&gt;Phone, tablet, and desktop/web layouts.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="products-and-customers"&gt;Products and customers&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;List, search, create, edit, and validate.&lt;/li&gt;
&lt;li&gt;Product image upload with progress and failure recovery.&lt;/li&gt;
&lt;li&gt;Paging or incremental loading.&lt;/li&gt;
&lt;li&gt;Updated timestamps for synchronization.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="orders"&gt;Orders&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Customer and product selection.&lt;/li&gt;
&lt;li&gt;Quantity, unit price, and domain-calculated total.&lt;/li&gt;
&lt;li&gt;Protection against empty orders and invalid quantity.&lt;/li&gt;
&lt;li&gt;Order status and consistent stock updates.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="continuity-and-notifications"&gt;Continuity and notifications&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Local cache for important reads.&lt;/li&gt;
&lt;li&gt;Clear stale-data and pending-operation feedback.&lt;/li&gt;
&lt;li&gt;A documented conflict and reconnection policy.&lt;/li&gt;
&lt;li&gt;Business-event notifications without sensitive payloads.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="expected-architecture"&gt;Expected architecture&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;lib/
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; core/
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; environment/
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; error/
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; network/
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; observability/
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; features/
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; auth/
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; dashboard/
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; products/
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; customers/
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; orders/
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; main.dart
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Each feature should separate domain, data, and presentation when its complexity justifies those boundaries. Do not create empty layers merely to satisfy a diagram; document decisions and exceptions in the README.&lt;/p&gt;</description></item><item><title>Flutter and Dart command and concept reference</title><link>https://ivaldo.eti.br/learn/flutter-dart/reference/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://ivaldo.eti.br/learn/flutter-dart/reference/</guid><description>&lt;p&gt;This page is a &lt;strong&gt;supporting reference&lt;/strong&gt;, not a replacement for the lessons. Return whenever you need to interpret a diagnostic, choose a command, or recall a concept. Examples assume a terminal opened at the project root, where &lt;code&gt;pubspec.yaml&lt;/code&gt; lives.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;In this reference:&lt;/strong&gt; &lt;a href="https://ivaldo.eti.br/learn/flutter-dart/reference/#how-to-read-a-command"&gt;reading commands&lt;/a&gt; · &lt;a href="https://ivaldo.eti.br/learn/flutter-dart/reference/#flutter-environment-and-diagnostics"&gt;Flutter diagnostics&lt;/a&gt; · &lt;a href="https://ivaldo.eti.br/learn/flutter-dart/reference/#project-creation-and-execution"&gt;creation and execution&lt;/a&gt; · &lt;a href="https://ivaldo.eti.br/learn/flutter-dart/reference/#dependencies-and-generation"&gt;dependencies&lt;/a&gt; · &lt;a href="https://ivaldo.eti.br/learn/flutter-dart/reference/#quality-and-tests"&gt;quality and tests&lt;/a&gt; · &lt;a href="https://ivaldo.eti.br/learn/flutter-dart/reference/#build-and-distribution"&gt;build&lt;/a&gt; · &lt;a href="https://ivaldo.eti.br/learn/flutter-dart/reference/#dart-tools"&gt;Dart tools&lt;/a&gt; · &lt;a href="https://ivaldo.eti.br/learn/flutter-dart/reference/#dart-language-glossary"&gt;Dart glossary&lt;/a&gt; · &lt;a href="https://ivaldo.eti.br/learn/flutter-dart/reference/#flutter-glossary"&gt;Flutter glossary&lt;/a&gt; · &lt;a href="https://ivaldo.eti.br/learn/flutter-dart/reference/#diagnostic-workflow"&gt;diagnostic workflow&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id="how-to-read-a-command"&gt;How to read a command&lt;/h2&gt;
&lt;p&gt;In &lt;code&gt;flutter run -d &amp;lt;deviceId&amp;gt; --debug&lt;/code&gt;:&lt;/p&gt;</description></item></channel></rss>