CINXE.COM
Add a user authentication flow to a Flutter app using FirebaseUI
<!doctype html> <html lang="en" dir="ltr"> <head> <meta name="google-signin-client-id" content="721724668570-nbkv1cfusk7kk4eni4pjvepaus73b13t.apps.googleusercontent.com"> <meta name="google-signin-scope" content="profile email https://www.googleapis.com/auth/developerprofiles https://www.googleapis.com/auth/developerprofiles.award"> <meta property="og:site_name" content="Firebase"> <meta property="og:type" content="website"><meta name="theme-color" content="#a8c7fa"><meta charset="utf-8"> <meta content="IE=Edge" http-equiv="X-UA-Compatible"> <meta name="viewport" content="width=device-width, initial-scale=1"> <link rel="manifest" href="/_pwa/firebase/manifest.json" crossorigin="use-credentials"> <link rel="preconnect" href="//www.gstatic.com" crossorigin> <link rel="preconnect" href="//fonts.gstatic.com" crossorigin> <link rel="preconnect" href="//fonts.googleapis.com" crossorigin> <link rel="preconnect" href="//apis.google.com" crossorigin> <link rel="preconnect" href="//www.google-analytics.com" crossorigin><link rel="stylesheet" href="//fonts.googleapis.com/css?family=Google+Sans:400,500|Roboto:400,400italic,500,500italic,700,700italic|Roboto+Mono:400,500,700&display=swap"> <link rel="stylesheet" href="//fonts.googleapis.com/css2?family=Material+Icons&family=Material+Symbols+Outlined&display=block"><link rel="stylesheet" href="https://www.gstatic.com/devrel-devsite/prod/v870e399c64f7c43c99a3043db4b3a74327bb93d0914e84a0c3dba90bbfd67625/firebase/css/app.css"> <link rel="stylesheet" href="https://www.gstatic.com/devrel-devsite/prod/v870e399c64f7c43c99a3043db4b3a74327bb93d0914e84a0c3dba90bbfd67625/firebase/css/dark-theme.css" disabled> <link rel="shortcut icon" href="https://www.gstatic.com/devrel-devsite/prod/v870e399c64f7c43c99a3043db4b3a74327bb93d0914e84a0c3dba90bbfd67625/firebase/images/favicon.png"> <link rel="apple-touch-icon" href="https://www.gstatic.com/devrel-devsite/prod/v870e399c64f7c43c99a3043db4b3a74327bb93d0914e84a0c3dba90bbfd67625/firebase/images/touchicon-180.png"><link rel="canonical" href="https://firebase.google.com/codelabs/firebase-auth-in-flutter-apps"><link rel="search" type="application/opensearchdescription+xml" title="Firebase" href="https://firebase.google.com/s/opensearch.xml"> <link rel="alternate" hreflang="en" href="https://firebase.google.com/codelabs/firebase-auth-in-flutter-apps" /><link rel="alternate" hreflang="x-default" href="https://firebase.google.com/codelabs/firebase-auth-in-flutter-apps" /><link rel="alternate" hreflang="ar" href="https://firebase.google.com/codelabs/firebase-auth-in-flutter-apps?hl=ar" /><link rel="alternate" hreflang="bn" href="https://firebase.google.com/codelabs/firebase-auth-in-flutter-apps?hl=bn" /><link rel="alternate" hreflang="zh-Hans" href="https://firebase.google.com/codelabs/firebase-auth-in-flutter-apps?hl=zh-cn" /><link rel="alternate" hreflang="zh-Hant" href="https://firebase.google.com/codelabs/firebase-auth-in-flutter-apps?hl=zh-tw" /><link rel="alternate" hreflang="fa" href="https://firebase.google.com/codelabs/firebase-auth-in-flutter-apps?hl=fa" /><link rel="alternate" hreflang="fr" href="https://firebase.google.com/codelabs/firebase-auth-in-flutter-apps?hl=fr" /><link rel="alternate" hreflang="de" href="https://firebase.google.com/codelabs/firebase-auth-in-flutter-apps?hl=de" /><link rel="alternate" hreflang="he" href="https://firebase.google.com/codelabs/firebase-auth-in-flutter-apps?hl=he" /><link rel="alternate" hreflang="hi" href="https://firebase.google.com/codelabs/firebase-auth-in-flutter-apps?hl=hi" /><link rel="alternate" hreflang="id" href="https://firebase.google.com/codelabs/firebase-auth-in-flutter-apps?hl=id" /><link rel="alternate" hreflang="it" href="https://firebase.google.com/codelabs/firebase-auth-in-flutter-apps?hl=it" /><link rel="alternate" hreflang="ja" href="https://firebase.google.com/codelabs/firebase-auth-in-flutter-apps?hl=ja" /><link rel="alternate" hreflang="ko" href="https://firebase.google.com/codelabs/firebase-auth-in-flutter-apps?hl=ko" /><link rel="alternate" hreflang="pl" href="https://firebase.google.com/codelabs/firebase-auth-in-flutter-apps?hl=pl" /><link rel="alternate" hreflang="pt-BR" href="https://firebase.google.com/codelabs/firebase-auth-in-flutter-apps?hl=pt-br" /><link rel="alternate" hreflang="pt" href="https://firebase.google.com/codelabs/firebase-auth-in-flutter-apps?hl=pt" /><link rel="alternate" hreflang="ru" href="https://firebase.google.com/codelabs/firebase-auth-in-flutter-apps?hl=ru" /><link rel="alternate" hreflang="es" href="https://firebase.google.com/codelabs/firebase-auth-in-flutter-apps?hl=es" /><link rel="alternate" hreflang="es-419" href="https://firebase.google.com/codelabs/firebase-auth-in-flutter-apps?hl=es-419" /><link rel="alternate" hreflang="th" href="https://firebase.google.com/codelabs/firebase-auth-in-flutter-apps?hl=th" /><link rel="alternate" hreflang="tr" href="https://firebase.google.com/codelabs/firebase-auth-in-flutter-apps?hl=tr" /><link rel="alternate" hreflang="vi" href="https://firebase.google.com/codelabs/firebase-auth-in-flutter-apps?hl=vi" /><title>Add a user authentication flow to a Flutter app using FirebaseUI</title> <meta property="og:title" content="Add a user authentication flow to a Flutter app using FirebaseUI"><meta name="description" content="In this codelab, you’ll learn how to add Firebase Authentication to a Flutter app with only a few lines of code."> <meta property="og:description" content="In this codelab, you’ll learn how to add Firebase Authentication to a Flutter app with only a few lines of code."><meta property="og:url" content="https://firebase.google.com/codelabs/firebase-auth-in-flutter-apps"><meta property="og:locale" content="en"> <link rel="stylesheet" href="/extras.css"></head> <body class="" template="codelab" theme="firebase-icy-theme" type="codelab" appearance layout="docs" concierge='closed' display-toc pending> <devsite-progress type="indeterminate" id="app-progress"></devsite-progress> <section class="devsite-wrapper"> <devsite-cookie-notification-bar></devsite-cookie-notification-bar><devsite-header role="banner" keep-tabs-visible> <div class="devsite-header--inner nocontent"> <div class="devsite-top-logo-row-wrapper-wrapper"> <div class="devsite-top-logo-row-wrapper"> <div class="devsite-top-logo-row"> <button type="button" id="devsite-hamburger-menu" class="devsite-header-icon-button button-flat material-icons gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Navigation menu button" visually-hidden aria-label="Open menu"> </button> <div class="devsite-product-name-wrapper"> <a href="/" class="devsite-site-logo-link gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Site logo" track-type="globalNav" track-name="firebase" track-metadata-position="nav" track-metadata-eventDetail="nav"> <picture> <source srcset="https://www.gstatic.com/devrel-devsite/prod/v870e399c64f7c43c99a3043db4b3a74327bb93d0914e84a0c3dba90bbfd67625/firebase/images/lockup.svg" media="(prefers-color-scheme: dark)" class="devsite-dark-theme" alt="Firebase"> <img src="https://www.gstatic.com/devrel-devsite/prod/v870e399c64f7c43c99a3043db4b3a74327bb93d0914e84a0c3dba90bbfd67625/firebase/images/lockup.svg" class="devsite-site-logo" alt="Firebase"> </picture> </a> </div> <div class="devsite-top-logo-row-middle"> <div class="devsite-header-upper-tabs"> </div> <devsite-search enable-signin enable-search enable-suggestions enable-query-completion tenant-name="Firebase" > <form class="devsite-search-form" action="https://firebase.google.com/s/results" method="GET"> <div class="devsite-search-container"> <button type="button" search-open class="devsite-search-button devsite-header-icon-button button-flat material-icons" aria-label="Open search"></button> <div class="devsite-searchbox"> <input aria-activedescendant="" aria-autocomplete="list" aria-label="Search" aria-expanded="false" aria-haspopup="listbox" autocomplete="off" class="devsite-search-field devsite-search-query" name="q" placeholder="Search" role="combobox" type="text" value="" > <div class="devsite-search-image material-icons" aria-hidden="true"> </div> <div class="devsite-search-shortcut-icon-container" aria-hidden="true"> <kbd class="devsite-search-shortcut-icon">/</kbd> </div> </div> </div> </form> <button type="button" search-close class="devsite-search-button devsite-header-icon-button button-flat material-icons" aria-label="Close search"></button> </devsite-search> </div> <devsite-appearance-selector></devsite-appearance-selector> <devsite-language-selector> <ul role="presentation"> <li role="presentation"> <a role="menuitem" lang="en" >English</a> </li> <li role="presentation"> <a role="menuitem" lang="de" >Deutsch</a> </li> <li role="presentation"> <a role="menuitem" lang="es" >Español</a> </li> <li role="presentation"> <a role="menuitem" lang="es_419" >Español – América Latina</a> </li> <li role="presentation"> <a role="menuitem" lang="fr" >Français</a> </li> <li role="presentation"> <a role="menuitem" lang="id" >Indonesia</a> </li> <li role="presentation"> <a role="menuitem" lang="it" >Italiano</a> </li> <li role="presentation"> <a role="menuitem" lang="pl" >Polski</a> </li> <li role="presentation"> <a role="menuitem" lang="pt" >Português</a> </li> <li role="presentation"> <a role="menuitem" lang="pt_br" >Português – Brasil</a> </li> <li role="presentation"> <a role="menuitem" lang="vi" >Tiếng Việt</a> </li> <li role="presentation"> <a role="menuitem" lang="tr" >Türkçe</a> </li> <li role="presentation"> <a role="menuitem" lang="ru" >Русский</a> </li> <li role="presentation"> <a role="menuitem" lang="he" >עברית</a> </li> <li role="presentation"> <a role="menuitem" lang="ar" >العربيّة</a> </li> <li role="presentation"> <a role="menuitem" lang="fa" >فارسی</a> </li> <li role="presentation"> <a role="menuitem" lang="hi" >हिंदी</a> </li> <li role="presentation"> <a role="menuitem" lang="bn" >বাংলা</a> </li> <li role="presentation"> <a role="menuitem" lang="th" >ภาษาไทย</a> </li> <li role="presentation"> <a role="menuitem" lang="zh_cn" >中文 – 简体</a> </li> <li role="presentation"> <a role="menuitem" lang="zh_tw" >中文 – 繁體</a> </li> <li role="presentation"> <a role="menuitem" lang="ja" >日本語</a> </li> <li role="presentation"> <a role="menuitem" lang="ko" >한국어</a> </li> </ul> </devsite-language-selector> <a class="devsite-header-link devsite-top-button button gc-analytics-event" href="//console.firebase.google.com" data-category="Site-Wide Custom Events" data-label="Site header link" > Go to console </a> <devsite-user enable-profiles fp-auth id="devsite-user"> <span class="button devsite-top-button" aria-hidden="true" visually-hidden>Sign in</span> </devsite-user> </div> </div> </div> </div> </devsite-header> <devsite-book-nav scrollbars hidden> <div class="devsite-book-nav-filter" hidden> <span class="filter-list-icon material-icons" aria-hidden="true"></span> <input type="text" placeholder="Filter" aria-label="Type to filter" role="searchbox"> <span class="filter-clear-button hidden" data-title="Clear filter" aria-label="Clear filter" role="button" tabindex="0"></span> </div> <nav class="devsite-book-nav devsite-nav nocontent" aria-label="Side menu"> <div class="devsite-mobile-header"> <button type="button" id="devsite-close-nav" class="devsite-header-icon-button button-flat material-icons gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Close navigation" aria-label="Close navigation"> </button> <div class="devsite-product-name-wrapper"> <a href="/" class="devsite-site-logo-link gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Site logo" track-type="globalNav" track-name="firebase" track-metadata-position="nav" track-metadata-eventDetail="nav"> <picture> <source srcset="https://www.gstatic.com/devrel-devsite/prod/v870e399c64f7c43c99a3043db4b3a74327bb93d0914e84a0c3dba90bbfd67625/firebase/images/lockup.svg" media="(prefers-color-scheme: dark)" class="devsite-dark-theme" alt="Firebase"> <img src="https://www.gstatic.com/devrel-devsite/prod/v870e399c64f7c43c99a3043db4b3a74327bb93d0914e84a0c3dba90bbfd67625/firebase/images/lockup.svg" class="devsite-site-logo" alt="Firebase"> </picture> </a> </div> </div> <div class="devsite-book-nav-wrapper"> <div class="devsite-mobile-nav-top"> <ul class="devsite-nav-list"> <li class="devsite-nav-item"> <a href="//console.firebase.google.com" class="devsite-nav-title gc-analytics-event " data-category="Site-Wide Custom Events" data-label="Responsive Tab: Go to console" track-type="navMenu" track-metadata-eventDetail="globalMenu" track-metadata-position="nav"> <span class="devsite-nav-text" tooltip > Go to console </span> </a> </li> </ul> </div> </div> </nav> </devsite-book-nav> <section id="gc-wrapper"> <main role="main" class="devsite-main-content" > <devsite-content> <article class="devsite-article"><style> body { transition: opacity ease-in 0.2s; } body[unresolved] { opacity: 0; display: block; overflow: hidden; position: relative; } </style> <div class="devsite-article-meta nocontent" role="navigation"> <ul class="devsite-breadcrumb-list" > </ul> </div> <h1 class="devsite-page-title" tabindex="-1"> Add a user authentication flow to a Flutter app using FirebaseUI </h1> <devsite-feature-tooltip ack-key="AckCollectionsBookmarkTooltipDismiss" analytics-category="Site-Wide Custom Events" analytics-action-show="Callout Profile displayed" analytics-action-close="Callout Profile dismissed" analytics-label="Create Collection Callout" class="devsite-page-bookmark-tooltip nocontent" dismiss-button="true" id="devsite-collections-dropdown" dismiss-button-text="Dismiss" close-button-text="Got it"> <devsite-bookmark></devsite-bookmark> <span slot="popout-heading"> Stay organized with collections </span> <span slot="popout-contents"> Save and categorize content based on your preferences. </span> </devsite-feature-tooltip> <devsite-toc class="devsite-nav" depth="1" devsite-toc-embedded > </devsite-toc> <div class="devsite-article-body clearfix "> <google-codelab-analytics gaid="UA-49880327-14" ga4id="G-JTFZSJVVVZ"></google-codelab-analytics> <google-codelab codelab-gaid="UA-52746336-1" codelab-ga4id="" doc-id="1BI-wemHE-MyqB2-VbA0NRf22AmeyPLEaKIB1yIO3JpM" id="codelabs/firebase-auth-in-flutter-apps" title="Add a user authentication flow to a Flutter app using FirebaseUI" no-tooltip="" environment="web" category="flutter,firebase" feedback-link="https://github.com/flutter/website/issues" layout="paginated" > <google-codelab-step label="Before you begin" duration="1" step="0"> <google-codelab-about codelab-title="Add a user authentication flow to a Flutter app using FirebaseUI" authors="Eric Windmill" last-updated="2024-11-01T13:19:31Z" duration="8"> </google-codelab-about> <h2 class="step-title" id="0" data-text="Before you begin" tabindex="-1"> 1. Before you begin </h2> <p>In this codelab, you'll learn how to add Firebase Authentication to your Flutter app using the FlutterFire UI package. With this package, you'll add both email/password auth and Google Sign In auth to a Flutter app. You'll also learn how to set up a Firebase project, and use the FlutterFire CLI to initialize Firebase in your Flutter app.</p> <h2 is-upgraded id="prerequisites" data-text="Prerequisites" tabindex="-1">Prerequisites</h2> <p>This codelab assumes that you have some Flutter experience. If not, you might want to first learn the basics. The following links are helpful:</p> <ul> <li>Take a <a href="https://flutter.io/widgets-intro/" target="_blank">Tour of the Flutter Widget Framework</a></li> <li>Try the <a href="https://codelabs.developers.google.com/codelabs/first-flutter-app-pt1" target="_blank">Write Your First Flutter App, part 1</a> codelab</li> </ul> <p>You should also have some Firebase experience, but it's okay if you've never added Firebase to a Flutter project. If you're unfamiliar with the Firebase console, or you're completely new to Firebase altogether, see the following links first:</p> <ul> <li><a href="https://firebase.google.com/docs/guides" target="_blank">Firebase Fundamentals docs</a></li> <li><a href="https://firebase.google.com/codelabs/firebase-get-to-know-flutter#0" target="_blank">Get to Know Firebase with Flutter codelab</a>.</li> </ul> <h2 is-upgraded id="what-youll-create" data-text="What you'll create" tabindex="-1">What you'll create</h2> <p>This codelab guides you through building the authentication flow for a Flutter app, using Firebase for Authentication. The application will have a login screen, a ‘Register' screen, a password recovery screen, and a user profile screen.</p> <p class="image-container"><img alt="6604fc9157f2c6ae.png" style="width: 288.00px" src="/static/codelabs/firebase-auth-in-flutter-apps/img/6604fc9157f2c6ae.png" srcset="https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/6604fc9157f2c6ae_36.png 36w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/6604fc9157f2c6ae_48.png 48w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/6604fc9157f2c6ae_72.png 72w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/6604fc9157f2c6ae_96.png 96w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/6604fc9157f2c6ae_480.png 480w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/6604fc9157f2c6ae_720.png 720w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/6604fc9157f2c6ae_856.png 856w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/6604fc9157f2c6ae_960.png 960w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/6604fc9157f2c6ae_1440.png 1440w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/6604fc9157f2c6ae_1920.png 1920w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/6604fc9157f2c6ae_2880.png 2880w" sizes="(max-width: 840px) 100vw, 856px"> <img alt="eab9509a41074930.png" style="width: 288.00px" src="/static/codelabs/firebase-auth-in-flutter-apps/img/eab9509a41074930.png" srcset="https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/eab9509a41074930_36.png 36w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/eab9509a41074930_48.png 48w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/eab9509a41074930_72.png 72w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/eab9509a41074930_96.png 96w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/eab9509a41074930_480.png 480w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/eab9509a41074930_720.png 720w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/eab9509a41074930_856.png 856w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/eab9509a41074930_960.png 960w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/eab9509a41074930_1440.png 1440w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/eab9509a41074930_1920.png 1920w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/eab9509a41074930_2880.png 2880w" sizes="(max-width: 840px) 100vw, 856px"> <img alt="da49189a5838e0bb.png" style="width: 288.00px" src="/static/codelabs/firebase-auth-in-flutter-apps/img/da49189a5838e0bb.png" srcset="https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/da49189a5838e0bb_36.png 36w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/da49189a5838e0bb_48.png 48w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/da49189a5838e0bb_72.png 72w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/da49189a5838e0bb_96.png 96w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/da49189a5838e0bb_480.png 480w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/da49189a5838e0bb_720.png 720w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/da49189a5838e0bb_856.png 856w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/da49189a5838e0bb_960.png 960w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/da49189a5838e0bb_1440.png 1440w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/da49189a5838e0bb_1920.png 1920w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/da49189a5838e0bb_2880.png 2880w" sizes="(max-width: 840px) 100vw, 856px"> <img alt="b2ccfb3632b77878.png" style="width: 288.00px" src="/static/codelabs/firebase-auth-in-flutter-apps/img/b2ccfb3632b77878.png" srcset="https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/b2ccfb3632b77878_36.png 36w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/b2ccfb3632b77878_48.png 48w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/b2ccfb3632b77878_72.png 72w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/b2ccfb3632b77878_96.png 96w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/b2ccfb3632b77878_480.png 480w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/b2ccfb3632b77878_720.png 720w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/b2ccfb3632b77878_856.png 856w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/b2ccfb3632b77878_960.png 960w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/b2ccfb3632b77878_1440.png 1440w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/b2ccfb3632b77878_1920.png 1920w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/b2ccfb3632b77878_2880.png 2880w" sizes="(max-width: 840px) 100vw, 856px"></p> <h2 class="checklist" is-upgraded id="what-youll-learn" data-text="What you'll learn" tabindex="-1">What you'll learn</h2> <p>This codelab covers:</p> <ul> <li>Adding Firebase to a Flutter app</li> <li>Firebase Console setup</li> <li>Using Firebase CLI to add Firebase to your application</li> <li>Using FlutterFire CLI to generate Firebase config in Dart</li> <li>Adding Firebase Authentication to your Flutter app</li> <li>Firebase Authentication setup in the console</li> <li>Adding Email and Password sign in with the <code translate="no" dir="ltr">firebase_ui_auth</code> package</li> <li>Adding user registration with the <code translate="no" dir="ltr">firebase_ui_auth</code> package</li> <li>Adding a ‘Forgot password?' page</li> <li>Adding Google Sign-in with <code translate="no" dir="ltr">firebase_ui_auth</code></li> <li>Configuring your app to work with multiple sign-in providers.</li> <li>Adding a user profile screen to your application with the <code translate="no" dir="ltr">firebase_ui_auth</code> package</li> </ul> <p>This codelab is specifically concerned with adding a robust Authentication system using the <code translate="no" dir="ltr">firebase_ui_auth</code> package. As you'll see, this entire app, with all of the above features, can be implemented with around 100 lines of code.</p> <h2 is-upgraded id="what-youll-need" data-text="What you'll need" tabindex="-1">What you'll need</h2> <ul> <li>Working knowledge of <a href="http://flutter.dev/getting-started" target="_blank">Flutter</a>, and the SDK installed</li> <li>A text editor (JetBrains IDE's, Android Studio, and VS Code are supported by Flutter)</li> <li>Google Chrome browser, or your other preferred development target for Flutter. (Some terminal commands in this codelab will assume you're running your app on Chrome)</li> </ul> </google-codelab-step> <google-codelab-step label="Create and set up a Firebase project" duration="7" step="1"> <h2 class="step-title" id="1" data-text="Create and set up a Firebase project" tabindex="-1"> 2. Create and set up a Firebase project </h2> <p>The first task you'll need to complete is creating a Firebase project in Firebase's web console.</p> <h2 is-upgraded id="create-a-firebase-project" data-text="Create a Firebase project" tabindex="-1">Create a Firebase project</h2> <ol type="1"> <li>Sign in to <a href="https://console.firebase.google.com/" target="_blank">Firebase</a>.</li> <li>In the Firebase console, click <strong>Add Project</strong> (or <strong>Create a project</strong>), and enter a name for your Firebase project (for example, "<strong>FlutterFire-UI-Codelab</strong>").</li> </ol> <p class="image-container"><img alt="df42a5e3d9584b48.png" style="width: 624.00px" src="/static/codelabs/firebase-auth-in-flutter-apps/img/df42a5e3d9584b48.png" srcset="https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/df42a5e3d9584b48_36.png 36w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/df42a5e3d9584b48_48.png 48w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/df42a5e3d9584b48_72.png 72w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/df42a5e3d9584b48_96.png 96w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/df42a5e3d9584b48_480.png 480w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/df42a5e3d9584b48_720.png 720w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/df42a5e3d9584b48_856.png 856w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/df42a5e3d9584b48_960.png 960w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/df42a5e3d9584b48_1440.png 1440w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/df42a5e3d9584b48_1920.png 1920w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/df42a5e3d9584b48_2880.png 2880w" sizes="(max-width: 840px) 100vw, 856px"></p> <ol type="1" start="3"> <li>Click through the project creation options. Accept the Firebase terms if prompted. Skip setting up Google Analytics, because you won't be using Analytics for this app.</li> </ol> <p class="image-container"><img alt="d1fcec48bf251eaa.png" style="width: 624.00px" src="/static/codelabs/firebase-auth-in-flutter-apps/img/d1fcec48bf251eaa.png" srcset="https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/d1fcec48bf251eaa_36.png 36w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/d1fcec48bf251eaa_48.png 48w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/d1fcec48bf251eaa_72.png 72w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/d1fcec48bf251eaa_96.png 96w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/d1fcec48bf251eaa_480.png 480w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/d1fcec48bf251eaa_720.png 720w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/d1fcec48bf251eaa_856.png 856w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/d1fcec48bf251eaa_960.png 960w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/d1fcec48bf251eaa_1440.png 1440w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/d1fcec48bf251eaa_1920.png 1920w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/d1fcec48bf251eaa_2880.png 2880w" sizes="(max-width: 840px) 100vw, 856px"></p> <p>To learn more about Firebase projects, see <a href="https://firebase.google.com/docs/projects/learn-more" target="_blank">Understand Firebase projects</a>.</p> <h2 is-upgraded id="enable-email-sign-in-for-firebase-authentication" data-text="Enable email sign-in for Firebase Authentication" tabindex="-1">Enable email sign-in for Firebase Authentication</h2> <p>The app that you're building uses <strong>Firebase Authentication</strong> to allow your users to sign in to your app. It also allows new users to register from the Flutter application.</p> <p><strong>Firebase Authentication</strong> needs to be enabled using the Firebase Console, and needs special configuration once enabled.</p> <p>To allow users to sign in to the web app, you'll first use the <strong>Email/Password</strong> sign-in method. Later, you'll add the <strong>Google Sign-In</strong> method.</p> <ol type="1"> <li>In the Firebase console, expand the <strong>Build</strong> menu in the left panel.</li> <li>Click <strong>Authentication</strong>, and then click the <strong>Get Started</strong> button, then the <strong>Sign-in method</strong> tab (or <a href="https://console.firebase.google.com/project/_/authentication/providers" target="_blank">click here</a> to go directly to the <strong>Sign-in method</strong> tab).</li> <li>Click <strong>Email/Password</strong> in the <strong>Sign-in providers</strong> list, set the <strong>Enable</strong> switch to the on position, and then click <strong>Save</strong>. <img alt="58e3e3e23c2f16a4.png" style="width: 624.00px" src="/static/codelabs/firebase-auth-in-flutter-apps/img/58e3e3e23c2f16a4.png" srcset="https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/58e3e3e23c2f16a4_36.png 36w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/58e3e3e23c2f16a4_48.png 48w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/58e3e3e23c2f16a4_72.png 72w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/58e3e3e23c2f16a4_96.png 96w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/58e3e3e23c2f16a4_480.png 480w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/58e3e3e23c2f16a4_720.png 720w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/58e3e3e23c2f16a4_856.png 856w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/58e3e3e23c2f16a4_960.png 960w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/58e3e3e23c2f16a4_1440.png 1440w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/58e3e3e23c2f16a4_1920.png 1920w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/58e3e3e23c2f16a4_2880.png 2880w" sizes="(max-width: 840px) 100vw, 856px"></li> </ol> </google-codelab-step> <google-codelab-step label="Set up Flutter app" duration="0" step="2"> <h2 class="step-title" id="2" data-text="Set up Flutter app" tabindex="-1"> 3. Set up Flutter app </h2> <p>You'll need to download the starter code, and install the Firebase CLI before we begin.</p> <h2 is-upgraded id="get-the-starter-code" data-text="Get the starter code" tabindex="-1">Get the starter code</h2> <p>Clone the <a href="https://github.com/flutter/codelabs" target="_blank">GitHub repository</a> from the command line:</p> <div></div><devsite-code><pre translate="no" dir="ltr" is-upgraded>git clone https://github.com/flutter/codelabs.git flutter-codelabs </pre></devsite-code> <p>Alternatively, if you have <a href="https://github.com/cli/cli" target="_blank">GitHub's </a>CLI tool installed:</p> <div></div><devsite-code><pre translate="no" dir="ltr" is-upgraded>gh repo clone flutter/codelabs flutter-codelabs </pre></devsite-code> <p>The sample code should be cloned into the <code translate="no" dir="ltr">flutter-codelabs</code> directory on your machine, which contains the code for a collection of codelabs. The code for this codelab is in the sub-directory <code translate="no" dir="ltr">flutter-codelabs/firebase-auth-flutterfire-ui</code>.</p> <p>The directory <code translate="no" dir="ltr">flutter-codelabs/firebase-auth-flutterfire-ui</code> contains two Flutter projects. One is called <code translate="no" dir="ltr">complete</code> and the other is called <code translate="no" dir="ltr">start</code>. The <code translate="no" dir="ltr">start</code> directory contains an incomplete project, and it's where you'll spend the most time.</p> <div></div><devsite-code><pre translate="no" dir="ltr" is-upgraded>cd flutter-codelabs/firebase-auth-flutterfire-ui/start </pre></devsite-code> <p>If you want to skip forward, or see what something should look like when complete, look in the directory named complete to cross-reference.</p> <p>If you want to follow along with the codelab, and add code yourself, you should start with the Flutter app at <code translate="no" dir="ltr">flutter-codelabs/firebase-auth-flutterfire-ui/start</code>, and add code to that project throughout the codelab. Open or import that directory into your preferred IDE.</p> <h2 is-upgraded id="install-firebase-cli" data-text="Install Firebase CLI" tabindex="-1">Install Firebase CLI</h2> <p>The Firebase CLI provides tools for managing your Firebase projects. The CLI is required for the FlutterFire CLI, which you'll install in a bit.</p> <p>There are a variety of ways to install the CLI. The simplest way, if you're using MacOS or Linux, is to run this command from your terminal:</p> <div></div><devsite-code><pre translate="no" dir="ltr" is-upgraded>curl -sL https://firebase.tools | bash </pre></devsite-code> <aside class="special"><p><strong>Note:</strong> If you're using Windows, or you prefer not to use <code translate="no" dir="ltr">curl</code>, you'll need to download a binary or use <code translate="no" dir="ltr">npm</code> to install. You can find all directions here: <a href="https://firebase.google.com/docs/cli#mac-linux-auto-script" target="_blank">https://firebase.google.com/docs/cli</a>. Return to this codelab after installing Firebase.</p> </aside> <p>After installing the CLI, you must authenticate with Firebase.</p> <ol type="1"> <li>Log into Firebase using your Google account by running the following command:</li> </ol> <div></div><devsite-code><pre translate="no" dir="ltr" is-upgraded>firebase login </pre></devsite-code> <ol type="1" start="2"> <li>This command connects your local machine to Firebase and grants you access to your Firebase projects.</li> </ol> <aside class="special"><p><strong>Note</strong>: The <code translate="no" dir="ltr">firebase login</code> command opens a web page that connects to localhost on your machine. If you're using a remote machine and don't have access to localhost, run the command with the flag <code translate="no" dir="ltr">--no-localhost</code>.</p> </aside> <ol type="1" start="3"> <li>Test that the CLI is properly installed and has access to your account by listing your Firebase projects. Run the following command:</li> </ol> <div></div><devsite-code><pre translate="no" dir="ltr" is-upgraded>firebase projects:list </pre></devsite-code> <ol type="1" start="4"> <li>The displayed list should be the same as the Firebase projects listed in the <a href="https://console.firebase.google.com/" target="_blank">Firebase console</a>. You should see at least <code translate="no" dir="ltr">flutterfire-ui-codelab.</code></li> </ol> <h2 is-upgraded id="install-the-flutterfire-cli" data-text="Install the FlutterFire CLI" tabindex="-1">Install the FlutterFire CLI</h2> <p>The FlutterFire CLI is a tool that helps ease the installation process of Firebase across all supported platforms in your Flutter app. It's built on top of the Firebase CLI.</p> <p>First, install the CLI:</p> <div></div><devsite-code><pre translate="no" dir="ltr" is-upgraded>dart pub global activate flutterfire_cli </pre></devsite-code> <p>Make sure the CLI was installed. Run the following command and ensure that the CLI outputs the help menu.</p> <div></div><devsite-code><pre translate="no" dir="ltr" is-upgraded>flutterfire -—help </pre></devsite-code> <h2 is-upgraded id="add-your-firebase-project-to-your-flutter-app" data-text="Add your Firebase project to your Flutter app" tabindex="-1">Add your Firebase project to your Flutter app</h2> <h3 is-upgraded id="configure-flutterfire" data-text="Configure FlutterFire" tabindex="-1">Configure FlutterFire</h3> <p>You can use FlutterFire to generate the needed Dart code to use Firebase in your Flutter app.</p> <div></div><devsite-code><pre translate="no" dir="ltr" is-upgraded>flutterfire configure </pre></devsite-code> <p>When this command is run, you'll be prompted to select which Firebase project you want to use, and which platforms you want to set up.</p> <p>The following screenshots show the prompts you'll need to answer.</p> <ol type="1"> <li>Select the project you want to use. In this case, use <code translate="no" dir="ltr">flutterfire-ui-codelab</code> <img alt="1359cdeb83204baa.png" style="width: 624.00px" src="/static/codelabs/firebase-auth-in-flutter-apps/img/1359cdeb83204baa.png" srcset="https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/1359cdeb83204baa_36.png 36w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/1359cdeb83204baa_48.png 48w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/1359cdeb83204baa_72.png 72w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/1359cdeb83204baa_96.png 96w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/1359cdeb83204baa_480.png 480w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/1359cdeb83204baa_720.png 720w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/1359cdeb83204baa_856.png 856w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/1359cdeb83204baa_960.png 960w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/1359cdeb83204baa_1440.png 1440w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/1359cdeb83204baa_1920.png 1920w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/1359cdeb83204baa_2880.png 2880w" sizes="(max-width: 840px) 100vw, 856px"></li> <li>Select which platforms you want to use. In this codelab, there are steps to configure Firebase Authentication for Flutter for web, iOS, and Android, but you can set up your Firebase project to use all options. <img alt="301c9534f594f472.png" style="width: 624.00px" src="/static/codelabs/firebase-auth-in-flutter-apps/img/301c9534f594f472.png" srcset="https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/301c9534f594f472_36.png 36w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/301c9534f594f472_48.png 48w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/301c9534f594f472_72.png 72w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/301c9534f594f472_96.png 96w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/301c9534f594f472_480.png 480w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/301c9534f594f472_720.png 720w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/301c9534f594f472_856.png 856w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/301c9534f594f472_960.png 960w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/301c9534f594f472_1440.png 1440w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/301c9534f594f472_1920.png 1920w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/301c9534f594f472_2880.png 2880w" sizes="(max-width: 840px) 100vw, 856px"></li> <li>This screenshot shows the output at the end of the process. If you're familiar with Firebase, you'll notice that you didn't have to create platform applications (for example, an Android application) in the console, and the FlutterFire CLI did it for you. <img alt="12199a85ade30459.png" style="width: 624.00px" src="/static/codelabs/firebase-auth-in-flutter-apps/img/12199a85ade30459.png" srcset="https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/12199a85ade30459_36.png 36w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/12199a85ade30459_48.png 48w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/12199a85ade30459_72.png 72w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/12199a85ade30459_96.png 96w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/12199a85ade30459_480.png 480w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/12199a85ade30459_720.png 720w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/12199a85ade30459_856.png 856w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/12199a85ade30459_960.png 960w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/12199a85ade30459_1440.png 1440w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/12199a85ade30459_1920.png 1920w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/12199a85ade30459_2880.png 2880w" sizes="(max-width: 840px) 100vw, 856px"></li> </ol> <p>When this is complete, look at the Flutter app in your text editor. FlutterFire CLI has generated a new file called <code translate="no" dir="ltr">firebase_options.dart</code>. This file contains a class called FirebaseOptions, which has static variables that hold the Firebase configuration needed for each platform. If you selected all platforms when you ran <code translate="no" dir="ltr">flutterfire configure</code>, you'll see static values named <code translate="no" dir="ltr">web</code>, <code translate="no" dir="ltr">android</code>, <code translate="no" dir="ltr">ios</code>, and <code translate="no" dir="ltr">macos</code>.</p> <h3 is-upgraded id="firebase_options.dart" data-text="firebase_options.dart" tabindex="-1"><a href="https://github.com/flutter/codelabs/firebase-auth-flutterfire-ui/complete/lib/firebase_options.dart" target="_blank">firebase_options.dart</a></h3> <div></div><devsite-code><pre class="devsite-click-to-copy" translate="no" dir="ltr" is-upgraded syntax="Python"><code language="language-dart" class="language-dart" translate="no" dir="ltr"><span class="devsite-syntax-kn">import</span> <span class="devsite-syntax-s1">'package:firebase_core/firebase_core.dart'</span> <span class="devsite-syntax-n">show</span> <span class="devsite-syntax-n">FirebaseOptions</span><span class="devsite-syntax-p">;</span> <span class="devsite-syntax-kn">import</span> <span class="devsite-syntax-s1">'package:flutter/foundation.dart'</span> <span class="devsite-syntax-n">show</span> <span class="devsite-syntax-n">defaultTargetPlatform</span><span class="devsite-syntax-p">,</span> <span class="devsite-syntax-n">kIsWeb</span><span class="devsite-syntax-p">,</span> <span class="devsite-syntax-n">TargetPlatform</span><span class="devsite-syntax-p">;</span> <span class="devsite-syntax-o">///</span> <span class="devsite-syntax-n">Default</span> <span class="devsite-syntax-p">[</span><span class="devsite-syntax-n">FirebaseOptions</span><span class="devsite-syntax-p">]</span> <span class="devsite-syntax-k">for</span> <span class="devsite-syntax-n">use</span> <span class="devsite-syntax-k">with</span> <span class="devsite-syntax-n">your</span> <span class="devsite-syntax-n">Firebase</span> <span class="devsite-syntax-n">apps</span><span class="devsite-syntax-o">.</span> <span class="devsite-syntax-o">///</span> <span class="devsite-syntax-o">///</span> <span class="devsite-syntax-n">Example</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-o">///</span> <span class="devsite-syntax-err">```</span><span class="devsite-syntax-n">dart</span> <span class="devsite-syntax-o">///</span> <span class="devsite-syntax-kn">import</span> <span class="devsite-syntax-s1">'firebase_options.dart'</span><span class="devsite-syntax-p">;</span> <span class="devsite-syntax-o">///</span> <span class="devsite-syntax-o">//</span> <span class="devsite-syntax-o">...</span> <span class="devsite-syntax-o">///</span> <span class="devsite-syntax-k">await</span> <span class="devsite-syntax-n">Firebase</span><span class="devsite-syntax-o">.</span><span class="devsite-syntax-n">initializeApp</span><span class="devsite-syntax-p">(</span> <span class="devsite-syntax-o">///</span> <span class="devsite-syntax-n">options</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-n">DefaultFirebaseOptions</span><span class="devsite-syntax-o">.</span><span class="devsite-syntax-n">currentPlatform</span><span class="devsite-syntax-p">,</span> <span class="devsite-syntax-o">///</span> <span class="devsite-syntax-p">);</span> <span class="devsite-syntax-o">///</span> <span class="devsite-syntax-err">```</span> <span class="devsite-syntax-k">class</span> <span class="devsite-syntax-nc">DefaultFirebaseOptions</span> <span class="devsite-syntax-p">{</span> <span class="devsite-syntax-n">static</span> <span class="devsite-syntax-n">FirebaseOptions</span> <span class="devsite-syntax-n">get</span> <span class="devsite-syntax-n">currentPlatform</span> <span class="devsite-syntax-p">{</span> <span class="devsite-syntax-k">if</span> <span class="devsite-syntax-p">(</span><span class="devsite-syntax-n">kIsWeb</span><span class="devsite-syntax-p">)</span> <span class="devsite-syntax-p">{</span> <span class="devsite-syntax-k">return</span> <span class="devsite-syntax-n">web</span><span class="devsite-syntax-p">;</span> <span class="devsite-syntax-p">}</span> <span class="devsite-syntax-o">//</span> <span class="devsite-syntax-n">ignore</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-n">missing_enum_constant_in_switch</span> <span class="devsite-syntax-n">switch</span> <span class="devsite-syntax-p">(</span><span class="devsite-syntax-n">defaultTargetPlatform</span><span class="devsite-syntax-p">)</span> <span class="devsite-syntax-p">{</span> <span class="devsite-syntax-k">case</span> <span class="devsite-syntax-n">TargetPlatform</span><span class="devsite-syntax-o">.</span><span class="devsite-syntax-n">android</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-k">return</span> <span class="devsite-syntax-n">android</span><span class="devsite-syntax-p">;</span> <span class="devsite-syntax-k">case</span> <span class="devsite-syntax-n">TargetPlatform</span><span class="devsite-syntax-o">.</span><span class="devsite-syntax-n">iOS</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-k">return</span> <span class="devsite-syntax-n">ios</span><span class="devsite-syntax-p">;</span> <span class="devsite-syntax-k">case</span> <span class="devsite-syntax-n">TargetPlatform</span><span class="devsite-syntax-o">.</span><span class="devsite-syntax-n">macOS</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-k">return</span> <span class="devsite-syntax-n">macos</span><span class="devsite-syntax-p">;</span> <span class="devsite-syntax-p">}</span> <span class="devsite-syntax-n">throw</span> <span class="devsite-syntax-n">UnsupportedError</span><span class="devsite-syntax-p">(</span> <span class="devsite-syntax-s1">'DefaultFirebaseOptions are not supported for this platform.'</span><span class="devsite-syntax-p">,</span> <span class="devsite-syntax-p">);</span> <span class="devsite-syntax-p">}</span> <span class="devsite-syntax-n">static</span> <span class="devsite-syntax-n">const</span> <span class="devsite-syntax-n">FirebaseOptions</span> <span class="devsite-syntax-n">web</span> <span class="devsite-syntax-o">=</span> <span class="devsite-syntax-n">FirebaseOptions</span><span class="devsite-syntax-p">(</span> <span class="devsite-syntax-n">apiKey</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-s1">'AIzaSyCqFjCV_9CZmYeIvcK9FVy4drmKUlSaIWY'</span><span class="devsite-syntax-p">,</span> <span class="devsite-syntax-n">appId</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-s1">'1:963656261848:web:7219f7fca5fc70afb237ad'</span><span class="devsite-syntax-p">,</span> <span class="devsite-syntax-n">messagingSenderId</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-s1">'963656261848'</span><span class="devsite-syntax-p">,</span> <span class="devsite-syntax-n">projectId</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-s1">'flutterfire-ui-codelab'</span><span class="devsite-syntax-p">,</span> <span class="devsite-syntax-n">authDomain</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-s1">'flutterfire-ui-codelab.firebaseapp.com'</span><span class="devsite-syntax-p">,</span> <span class="devsite-syntax-n">storageBucket</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-s1">'flutterfire-ui-codelab.firebasestorage.app'</span><span class="devsite-syntax-p">,</span> <span class="devsite-syntax-n">measurementId</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-s1">'G-DGF0CP099H'</span><span class="devsite-syntax-p">,</span> <span class="devsite-syntax-p">);</span> <span class="devsite-syntax-n">static</span> <span class="devsite-syntax-n">const</span> <span class="devsite-syntax-n">FirebaseOptions</span> <span class="devsite-syntax-n">android</span> <span class="devsite-syntax-o">=</span> <span class="devsite-syntax-n">FirebaseOptions</span><span class="devsite-syntax-p">(</span> <span class="devsite-syntax-n">apiKey</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-s1">'AIzaSyDconZaCQpkxIJ5KQBF-3tEU0rxYsLkIe8'</span><span class="devsite-syntax-p">,</span> <span class="devsite-syntax-n">appId</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-s1">'1:963656261848:android:c939ccc86ab2dcdbb237ad'</span><span class="devsite-syntax-p">,</span> <span class="devsite-syntax-n">messagingSenderId</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-s1">'963656261848'</span><span class="devsite-syntax-p">,</span> <span class="devsite-syntax-n">projectId</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-s1">'flutterfire-ui-codelab'</span><span class="devsite-syntax-p">,</span> <span class="devsite-syntax-n">storageBucket</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-s1">'flutterfire-ui-codelab.firebasestorage.app'</span><span class="devsite-syntax-p">,</span> <span class="devsite-syntax-p">);</span> <span class="devsite-syntax-n">static</span> <span class="devsite-syntax-n">const</span> <span class="devsite-syntax-n">FirebaseOptions</span> <span class="devsite-syntax-n">ios</span> <span class="devsite-syntax-o">=</span> <span class="devsite-syntax-n">FirebaseOptions</span><span class="devsite-syntax-p">(</span> <span class="devsite-syntax-n">apiKey</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-s1">'AIzaSyBqLWsqFjYAdGyihKTahMRDQMo0N6NVjAs'</span><span class="devsite-syntax-p">,</span> <span class="devsite-syntax-n">appId</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-s1">'1:963656261848:ios:d9e01cfe8b675dfcb237ad'</span><span class="devsite-syntax-p">,</span> <span class="devsite-syntax-n">messagingSenderId</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-s1">'963656261848'</span><span class="devsite-syntax-p">,</span> <span class="devsite-syntax-n">projectId</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-s1">'flutterfire-ui-codelab'</span><span class="devsite-syntax-p">,</span> <span class="devsite-syntax-n">storageBucket</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-s1">'flutterfire-ui-codelab.firebasestorage.app'</span><span class="devsite-syntax-p">,</span> <span class="devsite-syntax-n">iosClientId</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-s1">'963656261848-v7r3vq1v6haupv0l1mdrmsf56ktnua60.apps.googleusercontent.com'</span><span class="devsite-syntax-p">,</span> <span class="devsite-syntax-n">iosBundleId</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-s1">'com.example.complete'</span><span class="devsite-syntax-p">,</span> <span class="devsite-syntax-p">);</span> <span class="devsite-syntax-n">static</span> <span class="devsite-syntax-n">const</span> <span class="devsite-syntax-n">FirebaseOptions</span> <span class="devsite-syntax-n">macos</span> <span class="devsite-syntax-o">=</span> <span class="devsite-syntax-n">FirebaseOptions</span><span class="devsite-syntax-p">(</span> <span class="devsite-syntax-n">apiKey</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-s1">'AIzaSyBqLWsqFjYAdGyihKTahMRDQMo0N6NVjAs'</span><span class="devsite-syntax-p">,</span> <span class="devsite-syntax-n">appId</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-s1">'1:963656261848:ios:d9e01cfe8b675dfcb237ad'</span><span class="devsite-syntax-p">,</span> <span class="devsite-syntax-n">messagingSenderId</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-s1">'963656261848'</span><span class="devsite-syntax-p">,</span> <span class="devsite-syntax-n">projectId</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-s1">'flutterfire-ui-codelab'</span><span class="devsite-syntax-p">,</span> <span class="devsite-syntax-n">storageBucket</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-s1">'flutterfire-ui-codelab.firebasestorage.app'</span><span class="devsite-syntax-p">,</span> <span class="devsite-syntax-n">iosClientId</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-s1">'963656261848-v7r3vq1v6haupv0l1mdrmsf56ktnua60.apps.googleusercontent.com'</span><span class="devsite-syntax-p">,</span> <span class="devsite-syntax-n">iosBundleId</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-s1">'com.example.complete'</span><span class="devsite-syntax-p">,</span> <span class="devsite-syntax-p">);</span> <span class="devsite-syntax-p">}</span> </code></pre></devsite-code> <aside class="special"><p><strong>Note:</strong> Your file should contain different values for the API keys. It is perfectly safe to expose these keys to the public. <a href="https://medium.com/@paulbreslin/is-it-safe-to-expose-your-firebase-api-key-to-the-public-7e5bd01e637b" target="_blank">Read about it here</a>.</p> </aside> <p>Firebase uses the word application to refer to specific build for a specific platform in a Firebase project. For example, the Firebase project called FlutterFire-ui-codelab has multiple applications: one for Android, one for iOS, one for MacOS, and one for Web.</p> <p>The method <code translate="no" dir="ltr">DefaultFirebaseOptions.currentPlatform</code> uses the <code translate="no" dir="ltr">TargetPlatform</code> enum exposed by Flutter to detect the platform that your app is running on, and then returns the Firebase configuration values needed for the correct Firebase application.</p> <h2 is-upgraded id="add-firebase-packages-to-flutter-app" data-text="Add Firebase packages to Flutter app" tabindex="-1">Add Firebase packages to Flutter app</h2> <p>The final setup step is to add the relevant Firebase packages to your Flutter project. The <code translate="no" dir="ltr">firebase_options.dart</code> file should have errors, because it relies on Firebase packages that haven't been added yet. In the terminal, make sure you're in the root of the Flutter project at <code translate="no" dir="ltr">flutter-codelabs/firebase-emulator-suite/start</code>. Then, run the three following commands:</p> <div></div><devsite-code><pre translate="no" dir="ltr" is-upgraded>flutter pub add firebase_core </pre></devsite-code> <div></div><devsite-code><pre translate="no" dir="ltr" is-upgraded>flutter pub add firebase_auth </pre></devsite-code> <div></div><devsite-code><pre translate="no" dir="ltr" is-upgraded>flutter pub add firebase_ui_auth </pre></devsite-code> <p>These are the only packages you need at this point.</p> <h2 is-upgraded id="initialize-firebase" data-text="Initialize Firebase" tabindex="-1">Initialize Firebase</h2> <p>In order to use the packages added, and the <code translate="no" dir="ltr">DefaultFirebaseOptions.currentPlatform,</code> update the code in the <code translate="no" dir="ltr">main</code> function in the <code translate="no" dir="ltr">main.dart</code> file.</p> <h3 is-upgraded id="main.dart" data-text="main.dart" tabindex="-1"><a href="https://github.com/flutter/codelabs/firebase-auth-flutterfire-ui/complete/lib/main.dart" target="_blank">main.dart</a></h3> <div></div><devsite-code><pre class="devsite-click-to-copy" translate="no" dir="ltr" is-upgraded syntax="GDScript"><code language="language-dart" class="language-dart" translate="no" dir="ltr"><span class="devsite-syntax-nb devsite-syntax-nb-Type">void</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-n">main</span><span class="devsite-syntax-p">()</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-n">async</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-p">{</span> <span class="devsite-syntax-w"> </span><span class="devsite-syntax-n">WidgetsFlutterBinding</span><span class="devsite-syntax-o">.</span><span class="devsite-syntax-n">ensureInitialized</span><span class="devsite-syntax-p">();</span> <span class="devsite-syntax-w"> </span><span class="devsite-syntax-n">await</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-n">Firebase</span><span class="devsite-syntax-o">.</span><span class="devsite-syntax-n">initializeApp</span><span class="devsite-syntax-p">(</span> <span class="devsite-syntax-w"> </span><span class="devsite-syntax-n">options</span><span class="devsite-syntax-p">:</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-n">DefaultFirebaseOptions</span><span class="devsite-syntax-o">.</span><span class="devsite-syntax-n">currentPlatform</span><span class="devsite-syntax-p">,</span> <span class="devsite-syntax-w"> </span><span class="devsite-syntax-p">);</span> <span class="devsite-syntax-w"> </span><span class="devsite-syntax-n">runApp</span><span class="devsite-syntax-p">(</span><span class="devsite-syntax-k">const</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-n">MyApp</span><span class="devsite-syntax-p">());</span> <span class="devsite-syntax-p">}</span> </code></pre></devsite-code> <p>This code does two things.</p> <ol type="1"> <li><code translate="no" dir="ltr">WidgetsFlutterBinding.ensureInitialized()</code> tells Flutter not to start running the application widget code until the Flutter framework is completely booted. Firebase uses native platform channels, which require the framework to be running.</li> <li><code translate="no" dir="ltr">Firebase.initializeApp</code> sets up a connection between your Flutter app and your Firebase project. The <code translate="no" dir="ltr">DefaultFirebaseOptions.currentPlatform</code> is imported from our generated <code translate="no" dir="ltr">firebase_options.dart</code> file. This static value detects which platform you're running on, and passes in the corresponding Firebase keys.</li> </ol> </google-codelab-step> <google-codelab-step label="Add initial Firebase UI Auth page" duration="0" step="3"> <h2 class="step-title" id="3" data-text="Add initial Firebase UI Auth page" tabindex="-1"> 4. Add initial Firebase UI Auth page </h2> <p>Firebase UI for Auth provides widgets that represent entire screens in your application. These screens handle different authentication flows throughout your application, such as Sign In, Registration, Forgot Password, User Profile, and more. To get started, add a landing page to your app that acts as an authentication guard to the main application.</p> <h2 is-upgraded id="material-or-cupertino-app" data-text="Material or Cupertino App" tabindex="-1">Material or Cupertino App</h2> <p>FlutterFire UI requires that your application is wrapped in either a MaterialApp or CupertinoApp. Depending on your choice, the UI will automatically reflect the differences of Material or Cupertino widgets. For this codelab, use <code translate="no" dir="ltr">MaterialApp</code>, which is already added to the app in <code translate="no" dir="ltr">app.dart</code>.</p> <h3 is-upgraded id="app.dart" data-text="app.dart" tabindex="-1"><a href="https://github.com/flutter/codelabs/blob/main/firebase-auth-flutterfire-ui/start/lib/main.dart" target="_blank">app.dart</a></h3> <div></div><devsite-code><pre class="devsite-click-to-copy" translate="no" dir="ltr" is-upgraded syntax="Python"><code language="language-dart" class="language-dart" translate="no" dir="ltr"><span class="devsite-syntax-kn">import</span> <span class="devsite-syntax-s1">'package:flutter/material.dart'</span><span class="devsite-syntax-p">;</span> <span class="devsite-syntax-kn">import</span> <span class="devsite-syntax-s1">'auth_gate.dart'</span><span class="devsite-syntax-p">;</span> <span class="devsite-syntax-k">class</span> <span class="devsite-syntax-nc">MyApp</span> <span class="devsite-syntax-n">extends</span> <span class="devsite-syntax-n">StatelessWidget</span> <span class="devsite-syntax-p">{</span> <span class="devsite-syntax-n">const</span> <span class="devsite-syntax-n">MyApp</span><span class="devsite-syntax-p">({</span><span class="devsite-syntax-nb">super</span><span class="devsite-syntax-o">.</span><span class="devsite-syntax-n">key</span><span class="devsite-syntax-p">});</span> <span class="devsite-syntax-nd">@override</span> <span class="devsite-syntax-n">Widget</span> <span class="devsite-syntax-n">build</span><span class="devsite-syntax-p">(</span><span class="devsite-syntax-n">BuildContext</span> <span class="devsite-syntax-n">context</span><span class="devsite-syntax-p">)</span> <span class="devsite-syntax-p">{</span> <span class="devsite-syntax-k">return</span> <span class="devsite-syntax-n">MaterialApp</span><span class="devsite-syntax-p">(</span> <span class="devsite-syntax-n">theme</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-n">ThemeData</span><span class="devsite-syntax-p">(</span> <span class="devsite-syntax-n">primarySwatch</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-n">Colors</span><span class="devsite-syntax-o">.</span><span class="devsite-syntax-n">blue</span><span class="devsite-syntax-p">,</span> <span class="devsite-syntax-p">),</span> <span class="devsite-syntax-n">home</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-n">const</span> <span class="devsite-syntax-n">AuthGate</span><span class="devsite-syntax-p">(),</span> <span class="devsite-syntax-p">);</span> <span class="devsite-syntax-p">}</span> <span class="devsite-syntax-p">}</span> </code></pre></devsite-code> <h2 is-upgraded id="check-authentication-state" data-text="Check authentication state" tabindex="-1">Check authentication state</h2> <p>Before you can display a sign-in screen, you need to determine whether the user is currently authenticated. The most common way to check for this is to listen to FirebaseAuth's authStateChanges using the <a href="https://firebase.google.com/docs/auth/flutter/start#authstatechanges" target="_blank">Firebase Auth plugin</a>.</p> <p>In the code sample above, the <code translate="no" dir="ltr">MaterialApp</code> is building an <code translate="no" dir="ltr">AuthGate</code> widget in its build method. (This is a custom widget, not provided by FlutterFire UI.)</p> <p>That widget needs to be updated to include the <code translate="no" dir="ltr">authStateChanges</code> stream.</p> <p>The <code translate="no" dir="ltr">authStateChanges</code> API returns a <code translate="no" dir="ltr">Stream</code> with either the current user (if they are signed in), or null if they are not. To subscribe to this state in our application, you can use Flutter's <a href="https://api.flutter.dev/flutter/widgets/StreamBuilder-class.html" target="_blank">StreamBuilder</a> widget and pass the stream to it.</p> <p><code translate="no" dir="ltr">StreamBuilder</code> is a widget that builds itself based on the latest snapshot of data from a <a href="https://api.flutter.dev/flutter/dart-async/Stream-class.html" target="_blank">Stream</a> that you pass it. It automatically rebuilds when the Stream emits a new snapshot.</p> <p>Update the code in <code translate="no" dir="ltr">auth_gate.dart</code>.</p> <h3 is-upgraded id="auth_gate.dart" data-text="auth_gate.dart" tabindex="-1"><a href="https://github.com/flutter/codelabs/firebase-auth-flutterfire-ui/complete/lib/auth_gate.dart" target="_blank">auth_gate.dart</a></h3> <div></div><devsite-code><pre class="devsite-click-to-copy" translate="no" dir="ltr" is-upgraded syntax="Python"><code language="language-dart" class="language-dart" translate="no" dir="ltr"><span class="devsite-syntax-kn">import</span> <span class="devsite-syntax-s1">'package:firebase_auth/firebase_auth.dart'</span> <span class="devsite-syntax-n">hide</span> <span class="devsite-syntax-n">EmailAuthProvider</span><span class="devsite-syntax-p">;</span> <span class="devsite-syntax-kn">import</span> <span class="devsite-syntax-s1">'package:firebase_ui_auth/firebase_ui_auth.dart'</span><span class="devsite-syntax-p">;</span> <span class="devsite-syntax-kn">import</span> <span class="devsite-syntax-s1">'package:flutter/material.dart'</span><span class="devsite-syntax-p">;</span> <span class="devsite-syntax-kn">import</span> <span class="devsite-syntax-s1">'home.dart'</span><span class="devsite-syntax-p">;</span> <span class="devsite-syntax-k">class</span> <span class="devsite-syntax-nc">AuthGate</span> <span class="devsite-syntax-n">extends</span> <span class="devsite-syntax-n">StatelessWidget</span> <span class="devsite-syntax-p">{</span> <span class="devsite-syntax-n">const</span> <span class="devsite-syntax-n">AuthGate</span><span class="devsite-syntax-p">({</span><span class="devsite-syntax-nb">super</span><span class="devsite-syntax-o">.</span><span class="devsite-syntax-n">key</span><span class="devsite-syntax-p">});</span> <span class="devsite-syntax-nd">@override</span> <span class="devsite-syntax-n">Widget</span> <span class="devsite-syntax-n">build</span><span class="devsite-syntax-p">(</span><span class="devsite-syntax-n">BuildContext</span> <span class="devsite-syntax-n">context</span><span class="devsite-syntax-p">)</span> <span class="devsite-syntax-p">{</span> <span class="devsite-syntax-k">return</span> <span class="devsite-syntax-n">StreamBuilder<User</span><span class="devsite-syntax-err">?</span>><span class="devsite-syntax-p">(</span> <span class="devsite-syntax-n">stream</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-n">FirebaseAuth</span><span class="devsite-syntax-o">.</span><span class="devsite-syntax-n">instance</span><span class="devsite-syntax-o">.</span><span class="devsite-syntax-n">authStateChanges</span><span class="devsite-syntax-p">(),</span> <span class="devsite-syntax-n">builder</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-p">(</span><span class="devsite-syntax-n">context</span><span class="devsite-syntax-p">,</span> <span class="devsite-syntax-n">snapshot</span><span class="devsite-syntax-p">)</span> <span class="devsite-syntax-p">{</span> <span class="devsite-syntax-k">if</span> <span class="devsite-syntax-p">(</span><span class="devsite-syntax-err">!</span><span class="devsite-syntax-n">snapshot</span><span class="devsite-syntax-o">.</span><span class="devsite-syntax-n">hasData</span><span class="devsite-syntax-p">)</span> <span class="devsite-syntax-p">{</span> <span class="devsite-syntax-k">return</span> <span class="devsite-syntax-n">SignInScreen</span><span class="devsite-syntax-p">(</span> <span class="devsite-syntax-n">providers</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-p">[],</span> <span class="devsite-syntax-p">);</span> <span class="devsite-syntax-p">}</span> <span class="devsite-syntax-k">return</span> <span class="devsite-syntax-n">const</span> <span class="devsite-syntax-n">HomeScreen</span><span class="devsite-syntax-p">();</span> <span class="devsite-syntax-p">},</span> <span class="devsite-syntax-p">);</span> <span class="devsite-syntax-p">}</span> <span class="devsite-syntax-p">}</span> </code></pre></devsite-code> <ul> <li><code translate="no" dir="ltr">StreamBuilder.stream</code> is being passed <code translate="no" dir="ltr">FirebaseAuth.instance.authStateChanged</code>, the aforementioned stream, which will return a Firebase <code translate="no" dir="ltr">User</code> object if the user has authenticated. (Otherwise it will return <code translate="no" dir="ltr">null</code>.)</li> <li>Next, the code is using <code translate="no" dir="ltr">snapshot.hasData</code> to check if the value from the stream contains the <code translate="no" dir="ltr">User</code> object.</li> <li>If there isn't, it'll return a <code translate="no" dir="ltr">SignInScreen</code> widget. Currently, that screen won't do anything. This will be updated in the next step.</li> <li>Otherwise, it returns a <code translate="no" dir="ltr">HomeScreen</code>, which is the main part of the application that only authenticated users can access.</li> </ul> <p>The <code translate="no" dir="ltr">SignInScreen</code> is a widget that comes from the FlutterFire UI package. This will be the focus of the next step of this codelab. When you run the app at this point, you should see a blank sign-in screen.</p> </google-codelab-step> <google-codelab-step label="Sign-In screen" duration="0" step="4"> <h2 class="step-title" id="4" data-text="Sign-In screen" tabindex="-1"> 5. Sign-In screen </h2> <p>The <code translate="no" dir="ltr">SignInScreen</code> widget, provided by FlutterFire UI, adds the following functionality:</p> <ul> <li>Allows users to sign in</li> <li>If users forgot their password, they can tap "Forgot password?" and be taken to a form to reset their password</li> <li>If a user isn't yet registered, they can tap "Register", and be taken to another form that allows them to sign up.</li> </ul> <p>Again, this requires only a couple lines of code. Recall the code in the AuthGate widget:</p> <h3 is-upgraded id="auth_gate.dart_1" data-text="auth_gate.dart" tabindex="-1"><a href="https://github.com/flutter/codelabs/firebase-auth-flutterfire-ui/complete/lib/auth_gate.dart" target="_blank">auth_gate.dart</a></h3> <div></div><devsite-code><pre class="devsite-click-to-copy" translate="no" dir="ltr" is-upgraded syntax="Python"><code language="language-dart" class="language-dart" translate="no" dir="ltr"><span class="devsite-syntax-kn">import</span> <span class="devsite-syntax-s1">'package:firebase_auth/firebase_auth.dart'</span> <span class="devsite-syntax-n">hide</span> <span class="devsite-syntax-n">EmailAuthProvider</span><span class="devsite-syntax-p">;</span> <span class="devsite-syntax-kn">import</span> <span class="devsite-syntax-s1">'package:firebase_ui_auth/firebase_ui_auth.dart'</span><span class="devsite-syntax-p">;</span> <span class="devsite-syntax-kn">import</span> <span class="devsite-syntax-s1">'package:flutter/material.dart'</span><span class="devsite-syntax-p">;</span> <span class="devsite-syntax-kn">import</span> <span class="devsite-syntax-s1">'home.dart'</span><span class="devsite-syntax-p">;</span> <span class="devsite-syntax-k">class</span> <span class="devsite-syntax-nc">AuthGate</span> <span class="devsite-syntax-n">extends</span> <span class="devsite-syntax-n">StatelessWidget</span> <span class="devsite-syntax-p">{</span> <span class="devsite-syntax-n">const</span> <span class="devsite-syntax-n">AuthGate</span><span class="devsite-syntax-p">({</span><span class="devsite-syntax-nb">super</span><span class="devsite-syntax-o">.</span><span class="devsite-syntax-n">key</span><span class="devsite-syntax-p">});</span> <span class="devsite-syntax-nd">@override</span> <span class="devsite-syntax-n">Widget</span> <span class="devsite-syntax-n">build</span><span class="devsite-syntax-p">(</span><span class="devsite-syntax-n">BuildContext</span> <span class="devsite-syntax-n">context</span><span class="devsite-syntax-p">)</span> <span class="devsite-syntax-p">{</span> <span class="devsite-syntax-k">return</span> <span class="devsite-syntax-n">StreamBuilder<User</span><span class="devsite-syntax-err">?</span>><span class="devsite-syntax-p">(</span> <span class="devsite-syntax-n">stream</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-n">FirebaseAuth</span><span class="devsite-syntax-o">.</span><span class="devsite-syntax-n">instance</span><span class="devsite-syntax-o">.</span><span class="devsite-syntax-n">authStateChanges</span><span class="devsite-syntax-p">(),</span> <span class="devsite-syntax-n">builder</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-p">(</span><span class="devsite-syntax-n">context</span><span class="devsite-syntax-p">,</span> <span class="devsite-syntax-n">snapshot</span><span class="devsite-syntax-p">)</span> <span class="devsite-syntax-p">{</span> <span class="devsite-syntax-k">if</span> <span class="devsite-syntax-p">(</span><span class="devsite-syntax-err">!</span><span class="devsite-syntax-n">snapshot</span><span class="devsite-syntax-o">.</span><span class="devsite-syntax-n">hasData</span><span class="devsite-syntax-p">)</span> <span class="devsite-syntax-p">{</span> <span class="devsite-syntax-k">return</span> <span class="devsite-syntax-n">SignInScreen</span><span class="devsite-syntax-p">(</span> <span class="devsite-syntax-n">providers</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-p">[</span> <span class="devsite-syntax-n">EmailAuthProvider</span><span class="devsite-syntax-p">(),</span> <span class="devsite-syntax-o">//</span> <span class="devsite-syntax-n">new</span> <span class="devsite-syntax-p">],</span> <span class="devsite-syntax-p">);</span> <span class="devsite-syntax-p">}</span> <span class="devsite-syntax-k">return</span> <span class="devsite-syntax-n">const</span> <span class="devsite-syntax-n">HomeScreen</span><span class="devsite-syntax-p">();</span> <span class="devsite-syntax-p">},</span> <span class="devsite-syntax-p">);</span> <span class="devsite-syntax-p">}</span> <span class="devsite-syntax-p">}</span> </code></pre></devsite-code> <p>The <code translate="no" dir="ltr">SignInScreen</code> widget, and its <code translate="no" dir="ltr">providers</code> argument, is the only code required to get all the aforementioned functionality. You should now see a sign-in screen that has ‘email' and ‘password' text inputs, as well as a ‘Sign In' button.</p> <p>While functional, it lacks styling. The widget exposes parameters to customize the sign-in screen's look. For example, you might want to add your company's logo.</p> <h2 is-upgraded id="customize-the-sign-in-screen" data-text="Customize the sign-in Screen" tabindex="-1">Customize the sign-in Screen</h2> <h3 is-upgraded id="headerbuilder" data-text="headerBuilder" tabindex="-1">headerBuilder</h3> <p>Using the <code translate="no" dir="ltr">SignInScreen.headerBuilder</code> argument, you can add whatever widgets you want above the sign-in form. This widget is only displayed on narrow screens, such as mobile devices. On wide screens, you can use <code translate="no" dir="ltr">SignInScreen.sideBuilder</code>, which is discussed later in this codelab.</p> <p>Update the <code translate="no" dir="ltr">auth_gate.dart</code> file with this code:</p> <h3 is-upgraded id="auth_gate.dart_2" data-text="auth_gate.dart" tabindex="-1"><a href="https://github.com/flutter/codelabs/firebase-auth-flutterfire-ui/complete/lib/auth_gate.dart" target="_blank">auth_gate.dart</a></h3> <div></div><devsite-code><pre class="devsite-click-to-copy" translate="no" dir="ltr" is-upgraded syntax="Python"><code language="language-dart" class="language-dart" translate="no" dir="ltr"><span class="devsite-syntax-kn">import</span> <span class="devsite-syntax-s1">'package:firebase_auth/firebase_auth.dart'</span> <span class="devsite-syntax-n">hide</span> <span class="devsite-syntax-n">EmailAuthProvider</span><span class="devsite-syntax-p">;</span> <span class="devsite-syntax-kn">import</span> <span class="devsite-syntax-s1">'package:firebase_ui_auth/firebase_ui_auth.dart'</span><span class="devsite-syntax-p">;</span> <span class="devsite-syntax-kn">import</span> <span class="devsite-syntax-s1">'package:flutter/material.dart'</span><span class="devsite-syntax-p">;</span> <span class="devsite-syntax-kn">import</span> <span class="devsite-syntax-s1">'home.dart'</span><span class="devsite-syntax-p">;</span> <span class="devsite-syntax-k">class</span> <span class="devsite-syntax-nc">AuthGate</span> <span class="devsite-syntax-n">extends</span> <span class="devsite-syntax-n">StatelessWidget</span> <span class="devsite-syntax-p">{</span> <span class="devsite-syntax-n">const</span> <span class="devsite-syntax-n">AuthGate</span><span class="devsite-syntax-p">({</span><span class="devsite-syntax-nb">super</span><span class="devsite-syntax-o">.</span><span class="devsite-syntax-n">key</span><span class="devsite-syntax-p">});</span> <span class="devsite-syntax-nd">@override</span> <span class="devsite-syntax-n">Widget</span> <span class="devsite-syntax-n">build</span><span class="devsite-syntax-p">(</span><span class="devsite-syntax-n">BuildContext</span> <span class="devsite-syntax-n">context</span><span class="devsite-syntax-p">)</span> <span class="devsite-syntax-p">{</span> <span class="devsite-syntax-k">return</span> <span class="devsite-syntax-n">StreamBuilder<User</span><span class="devsite-syntax-err">?</span>><span class="devsite-syntax-p">(</span> <span class="devsite-syntax-n">stream</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-n">FirebaseAuth</span><span class="devsite-syntax-o">.</span><span class="devsite-syntax-n">instance</span><span class="devsite-syntax-o">.</span><span class="devsite-syntax-n">authStateChanges</span><span class="devsite-syntax-p">(),</span> <span class="devsite-syntax-n">builder</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-p">(</span><span class="devsite-syntax-n">context</span><span class="devsite-syntax-p">,</span> <span class="devsite-syntax-n">snapshot</span><span class="devsite-syntax-p">)</span> <span class="devsite-syntax-p">{</span> <span class="devsite-syntax-k">if</span> <span class="devsite-syntax-p">(</span><span class="devsite-syntax-err">!</span><span class="devsite-syntax-n">snapshot</span><span class="devsite-syntax-o">.</span><span class="devsite-syntax-n">hasData</span><span class="devsite-syntax-p">)</span> <span class="devsite-syntax-p">{</span> <span class="devsite-syntax-k">return</span> <span class="devsite-syntax-n">SignInScreen</span><span class="devsite-syntax-p">(</span> <span class="devsite-syntax-n">providers</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-p">[</span> <span class="devsite-syntax-n">EmailAuthProvider</span><span class="devsite-syntax-p">(),</span> <span class="devsite-syntax-p">],</span> <span class="devsite-syntax-n">headerBuilder</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-p">(</span><span class="devsite-syntax-n">context</span><span class="devsite-syntax-p">,</span> <span class="devsite-syntax-n">constraints</span><span class="devsite-syntax-p">,</span> <span class="devsite-syntax-n">shrinkOffset</span><span class="devsite-syntax-p">)</span> <span class="devsite-syntax-p">{</span> <span class="devsite-syntax-k">return</span> <span class="devsite-syntax-n">Padding</span><span class="devsite-syntax-p">(</span> <span class="devsite-syntax-n">padding</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-n">const</span> <span class="devsite-syntax-n">EdgeInsets</span><span class="devsite-syntax-o">.</span><span class="devsite-syntax-n">all</span><span class="devsite-syntax-p">(</span><span class="devsite-syntax-mi">20</span><span class="devsite-syntax-p">),</span> <span class="devsite-syntax-n">child</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-n">AspectRatio</span><span class="devsite-syntax-p">(</span> <span class="devsite-syntax-n">aspectRatio</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-mi">1</span><span class="devsite-syntax-p">,</span> <span class="devsite-syntax-n">child</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-n">Image</span><span class="devsite-syntax-o">.</span><span class="devsite-syntax-n">asset</span><span class="devsite-syntax-p">(</span><span class="devsite-syntax-s1">'assets/flutterfire_300x.png'</span><span class="devsite-syntax-p">),</span> <span class="devsite-syntax-p">),</span> <span class="devsite-syntax-p">);</span> <span class="devsite-syntax-p">},</span> <span class="devsite-syntax-p">);</span> <span class="devsite-syntax-p">}</span> <span class="devsite-syntax-k">return</span> <span class="devsite-syntax-n">const</span> <span class="devsite-syntax-n">HomeScreen</span><span class="devsite-syntax-p">();</span> <span class="devsite-syntax-p">},</span> <span class="devsite-syntax-p">);</span> <span class="devsite-syntax-p">}</span> <span class="devsite-syntax-p">}</span> </code></pre></devsite-code> <p>The headerBuilder argument requires a function of the type HeaderBuilder, which is defined in the FlutterFire UI package.</p> <div></div><devsite-code><pre class="devsite-click-to-copy" translate="no" dir="ltr" is-upgraded syntax="Carbon"><code language="language-dart" class="language-dart" translate="no" dir="ltr"><span class="devsite-syntax-nx">typedef</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-nx">HeaderBuilder</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-p">=</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-nx">Widget</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-nx">Function</span><span class="devsite-syntax-p">(</span> <span class="devsite-syntax-w"> </span><span class="devsite-syntax-nx">BuildContext</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-nx">context</span><span class="devsite-syntax-p">,</span> <span class="devsite-syntax-w"> </span><span class="devsite-syntax-nx">BoxConstraints</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-nx">constraints</span><span class="devsite-syntax-p">,</span> <span class="devsite-syntax-w"> </span><span class="devsite-syntax-nx">double</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-nx">shrinkOffset</span><span class="devsite-syntax-p">,</span> <span class="devsite-syntax-p">);</span> </code></pre></devsite-code> <p>Because it's a callback, it exposes values you could use, such as the <code translate="no" dir="ltr">BuildContext</code> and <code translate="no" dir="ltr">BoxConstraints</code>, and requires you return a widget. Whichever widget you return is displayed at the top of the screen. In this example, the new code adds an image to the top of the screen. Your application should now look like this.</p> <p class="image-container"><img alt="73d7548d91bbd2ab.png" style="width: 288.00px" src="/static/codelabs/firebase-auth-in-flutter-apps/img/73d7548d91bbd2ab.png" srcset="https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/73d7548d91bbd2ab_36.png 36w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/73d7548d91bbd2ab_48.png 48w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/73d7548d91bbd2ab_72.png 72w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/73d7548d91bbd2ab_96.png 96w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/73d7548d91bbd2ab_480.png 480w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/73d7548d91bbd2ab_720.png 720w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/73d7548d91bbd2ab_856.png 856w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/73d7548d91bbd2ab_960.png 960w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/73d7548d91bbd2ab_1440.png 1440w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/73d7548d91bbd2ab_1920.png 1920w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/73d7548d91bbd2ab_2880.png 2880w" sizes="(max-width: 840px) 100vw, 856px"></p> <h3 is-upgraded id="subtitle-builder" data-text="Subtitle Builder" tabindex="-1">Subtitle Builder</h3> <p>The sign-in screen exposes three additional parameters that allow you to customize the screen: <code translate="no" dir="ltr">subtitleBuilder</code>, <code translate="no" dir="ltr">footerBuilder</code>, and <code translate="no" dir="ltr">sideBuilder</code>.</p> <p>The <code translate="no" dir="ltr">subtitleBuilder</code> is slightly different in that the callback arguments include an action, which is of type <code translate="no" dir="ltr">AuthAction</code>. <code translate="no" dir="ltr">AuthAction</code> is an enum that you can use to detect if the screen the user is on is the "sign in" screen or the "register" screen.</p> <p>Update the code in auth_gate.dart to use the subtitleBuilder.</p> <h3 is-upgraded id="auth_gate.dart_3" data-text="auth_gate.dart" tabindex="-1"><a href="https://github.com/flutter/codelabs/firebase-auth-flutterfire-ui/complete/lib/auth_gate.dart" target="_blank">auth_gate.dart</a></h3> <div></div><devsite-code><pre class="devsite-click-to-copy" translate="no" dir="ltr" is-upgraded syntax="Python"><code language="language-dart" class="language-dart" translate="no" dir="ltr"><span class="devsite-syntax-kn">import</span> <span class="devsite-syntax-s1">'package:firebase_auth/firebase_auth.dart'</span> <span class="devsite-syntax-n">hide</span> <span class="devsite-syntax-n">EmailAuthProvider</span><span class="devsite-syntax-p">;</span> <span class="devsite-syntax-kn">import</span> <span class="devsite-syntax-s1">'package:firebase_ui_auth/firebase_ui_auth.dart'</span><span class="devsite-syntax-p">;</span> <span class="devsite-syntax-kn">import</span> <span class="devsite-syntax-s1">'package:flutter/material.dart'</span><span class="devsite-syntax-p">;</span> <span class="devsite-syntax-kn">import</span> <span class="devsite-syntax-s1">'home.dart'</span><span class="devsite-syntax-p">;</span> <span class="devsite-syntax-k">class</span> <span class="devsite-syntax-nc">AuthGate</span> <span class="devsite-syntax-n">extends</span> <span class="devsite-syntax-n">StatelessWidget</span> <span class="devsite-syntax-p">{</span> <span class="devsite-syntax-n">const</span> <span class="devsite-syntax-n">AuthGate</span><span class="devsite-syntax-p">({</span><span class="devsite-syntax-nb">super</span><span class="devsite-syntax-o">.</span><span class="devsite-syntax-n">key</span><span class="devsite-syntax-p">});</span> <span class="devsite-syntax-nd">@override</span> <span class="devsite-syntax-n">Widget</span> <span class="devsite-syntax-n">build</span><span class="devsite-syntax-p">(</span><span class="devsite-syntax-n">BuildContext</span> <span class="devsite-syntax-n">context</span><span class="devsite-syntax-p">)</span> <span class="devsite-syntax-p">{</span> <span class="devsite-syntax-k">return</span> <span class="devsite-syntax-n">StreamBuilder<User</span><span class="devsite-syntax-err">?</span>><span class="devsite-syntax-p">(</span> <span class="devsite-syntax-n">stream</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-n">FirebaseAuth</span><span class="devsite-syntax-o">.</span><span class="devsite-syntax-n">instance</span><span class="devsite-syntax-o">.</span><span class="devsite-syntax-n">authStateChanges</span><span class="devsite-syntax-p">(),</span> <span class="devsite-syntax-n">builder</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-p">(</span><span class="devsite-syntax-n">context</span><span class="devsite-syntax-p">,</span> <span class="devsite-syntax-n">snapshot</span><span class="devsite-syntax-p">)</span> <span class="devsite-syntax-p">{</span> <span class="devsite-syntax-k">if</span> <span class="devsite-syntax-p">(</span><span class="devsite-syntax-err">!</span><span class="devsite-syntax-n">snapshot</span><span class="devsite-syntax-o">.</span><span class="devsite-syntax-n">hasData</span><span class="devsite-syntax-p">)</span> <span class="devsite-syntax-p">{</span> <span class="devsite-syntax-k">return</span> <span class="devsite-syntax-n">SignInScreen</span><span class="devsite-syntax-p">(</span> <span class="devsite-syntax-n">providers</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-p">[</span> <span class="devsite-syntax-n">EmailAuthProvider</span><span class="devsite-syntax-p">()</span> <span class="devsite-syntax-p">],</span> <span class="devsite-syntax-n">headerBuilder</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-p">(</span><span class="devsite-syntax-n">context</span><span class="devsite-syntax-p">,</span> <span class="devsite-syntax-n">constraints</span><span class="devsite-syntax-p">,</span> <span class="devsite-syntax-n">shrinkOffset</span><span class="devsite-syntax-p">)</span> <span class="devsite-syntax-p">{</span> <span class="devsite-syntax-k">return</span> <span class="devsite-syntax-n">Padding</span><span class="devsite-syntax-p">(</span> <span class="devsite-syntax-n">padding</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-n">const</span> <span class="devsite-syntax-n">EdgeInsets</span><span class="devsite-syntax-o">.</span><span class="devsite-syntax-n">all</span><span class="devsite-syntax-p">(</span><span class="devsite-syntax-mi">20</span><span class="devsite-syntax-p">),</span> <span class="devsite-syntax-n">child</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-n">AspectRatio</span><span class="devsite-syntax-p">(</span> <span class="devsite-syntax-n">aspectRatio</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-mi">1</span><span class="devsite-syntax-p">,</span> <span class="devsite-syntax-n">child</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-n">Image</span><span class="devsite-syntax-o">.</span><span class="devsite-syntax-n">asset</span><span class="devsite-syntax-p">(</span><span class="devsite-syntax-s1">'flutterfire_300x.png'</span><span class="devsite-syntax-p">),</span> <span class="devsite-syntax-p">),</span> <span class="devsite-syntax-p">);</span> <span class="devsite-syntax-p">},</span> <span class="devsite-syntax-n">subtitleBuilder</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-p">(</span><span class="devsite-syntax-n">context</span><span class="devsite-syntax-p">,</span> <span class="devsite-syntax-n">action</span><span class="devsite-syntax-p">)</span> <span class="devsite-syntax-p">{</span> <span class="devsite-syntax-k">return</span> <span class="devsite-syntax-n">Padding</span><span class="devsite-syntax-p">(</span> <span class="devsite-syntax-n">padding</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-n">const</span> <span class="devsite-syntax-n">EdgeInsets</span><span class="devsite-syntax-o">.</span><span class="devsite-syntax-n">symmetric</span><span class="devsite-syntax-p">(</span><span class="devsite-syntax-n">vertical</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-mf">8.0</span><span class="devsite-syntax-p">),</span> <span class="devsite-syntax-n">child</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-n">action</span> <span class="devsite-syntax-o">==</span> <span class="devsite-syntax-n">AuthAction</span><span class="devsite-syntax-o">.</span><span class="devsite-syntax-n">signIn</span> <span class="devsite-syntax-err">?</span> <span class="devsite-syntax-n">const</span> <span class="devsite-syntax-n">Text</span><span class="devsite-syntax-p">(</span><span class="devsite-syntax-s1">'Welcome to FlutterFire, please sign in!'</span><span class="devsite-syntax-p">)</span> <span class="devsite-syntax-p">:</span> <span class="devsite-syntax-n">const</span> <span class="devsite-syntax-n">Text</span><span class="devsite-syntax-p">(</span><span class="devsite-syntax-s1">'Welcome to Flutterfire, please sign up!'</span><span class="devsite-syntax-p">),</span> <span class="devsite-syntax-p">);</span> <span class="devsite-syntax-p">},</span> <span class="devsite-syntax-p">);</span> <span class="devsite-syntax-p">}</span> <span class="devsite-syntax-k">return</span> <span class="devsite-syntax-n">const</span> <span class="devsite-syntax-n">HomeScreen</span><span class="devsite-syntax-p">();</span> <span class="devsite-syntax-p">},</span> <span class="devsite-syntax-p">);</span> <span class="devsite-syntax-p">}</span> <span class="devsite-syntax-p">}</span> </code></pre></devsite-code> <p>Reload the application, and it should look like this</p> <h2 is-upgraded id="footer-builder" data-text="Footer builder" tabindex="-1">Footer builder</h2> <p>The footerBuilder argument is the same as the subtitleBuilder. It doesn't expose <code translate="no" dir="ltr">BoxConstraints</code> or <code translate="no" dir="ltr">shrinkOffset</code>, as it's intended for text rather than images. (Although you can add any widget you want.)</p> <p>Add a footer to your sign-in screen with this code.</p> <h3 is-upgraded id="auth_gate.dart_4" data-text="auth_gate.dart" tabindex="-1"><a href="https://github.com/flutter/codelabs/firebase-auth-flutterfire-ui/complete/lib/auth_gate.dart" target="_blank">auth_gate.dart</a></h3> <div></div><devsite-code><pre class="devsite-click-to-copy" translate="no" dir="ltr" is-upgraded syntax="Python"><code language="language-dart" class="language-dart" translate="no" dir="ltr"><span class="devsite-syntax-kn">import</span> <span class="devsite-syntax-s1">'package:firebase_auth/firebase_auth.dart'</span> <span class="devsite-syntax-n">hide</span> <span class="devsite-syntax-n">EmailAuthProvider</span><span class="devsite-syntax-p">;</span> <span class="devsite-syntax-kn">import</span> <span class="devsite-syntax-s1">'package:firebase_ui_auth/firebase_ui_auth.dart'</span><span class="devsite-syntax-p">;</span> <span class="devsite-syntax-kn">import</span> <span class="devsite-syntax-s1">'package:flutter/material.dart'</span><span class="devsite-syntax-p">;</span> <span class="devsite-syntax-kn">import</span> <span class="devsite-syntax-s1">'home.dart'</span><span class="devsite-syntax-p">;</span> <span class="devsite-syntax-k">class</span> <span class="devsite-syntax-nc">AuthGate</span> <span class="devsite-syntax-n">extends</span> <span class="devsite-syntax-n">StatelessWidget</span> <span class="devsite-syntax-p">{</span> <span class="devsite-syntax-n">const</span> <span class="devsite-syntax-n">AuthGate</span><span class="devsite-syntax-p">({</span><span class="devsite-syntax-nb">super</span><span class="devsite-syntax-o">.</span><span class="devsite-syntax-n">key</span><span class="devsite-syntax-p">});</span> <span class="devsite-syntax-nd">@override</span> <span class="devsite-syntax-n">Widget</span> <span class="devsite-syntax-n">build</span><span class="devsite-syntax-p">(</span><span class="devsite-syntax-n">BuildContext</span> <span class="devsite-syntax-n">context</span><span class="devsite-syntax-p">)</span> <span class="devsite-syntax-p">{</span> <span class="devsite-syntax-k">return</span> <span class="devsite-syntax-n">StreamBuilder<User</span><span class="devsite-syntax-err">?</span>><span class="devsite-syntax-p">(</span> <span class="devsite-syntax-n">stream</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-n">FirebaseAuth</span><span class="devsite-syntax-o">.</span><span class="devsite-syntax-n">instance</span><span class="devsite-syntax-o">.</span><span class="devsite-syntax-n">authStateChanges</span><span class="devsite-syntax-p">(),</span> <span class="devsite-syntax-n">builder</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-p">(</span><span class="devsite-syntax-n">context</span><span class="devsite-syntax-p">,</span> <span class="devsite-syntax-n">snapshot</span><span class="devsite-syntax-p">)</span> <span class="devsite-syntax-p">{</span> <span class="devsite-syntax-k">if</span> <span class="devsite-syntax-p">(</span><span class="devsite-syntax-err">!</span><span class="devsite-syntax-n">snapshot</span><span class="devsite-syntax-o">.</span><span class="devsite-syntax-n">hasData</span><span class="devsite-syntax-p">)</span> <span class="devsite-syntax-p">{</span> <span class="devsite-syntax-k">return</span> <span class="devsite-syntax-n">SignInScreen</span><span class="devsite-syntax-p">(</span> <span class="devsite-syntax-n">providers</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-p">[</span> <span class="devsite-syntax-n">EmailAuthProvider</span><span class="devsite-syntax-p">()</span> <span class="devsite-syntax-p">],</span> <span class="devsite-syntax-n">headerBuilder</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-p">(</span><span class="devsite-syntax-n">context</span><span class="devsite-syntax-p">,</span> <span class="devsite-syntax-n">constraints</span><span class="devsite-syntax-p">,</span> <span class="devsite-syntax-n">shrinkOffset</span><span class="devsite-syntax-p">)</span> <span class="devsite-syntax-p">{</span> <span class="devsite-syntax-k">return</span> <span class="devsite-syntax-n">Padding</span><span class="devsite-syntax-p">(</span> <span class="devsite-syntax-n">padding</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-n">const</span> <span class="devsite-syntax-n">EdgeInsets</span><span class="devsite-syntax-o">.</span><span class="devsite-syntax-n">all</span><span class="devsite-syntax-p">(</span><span class="devsite-syntax-mi">20</span><span class="devsite-syntax-p">),</span> <span class="devsite-syntax-n">child</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-n">AspectRatio</span><span class="devsite-syntax-p">(</span> <span class="devsite-syntax-n">aspectRatio</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-mi">1</span><span class="devsite-syntax-p">,</span> <span class="devsite-syntax-n">child</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-n">Image</span><span class="devsite-syntax-o">.</span><span class="devsite-syntax-n">asset</span><span class="devsite-syntax-p">(</span><span class="devsite-syntax-s1">'flutterfire_300x.png'</span><span class="devsite-syntax-p">),</span> <span class="devsite-syntax-p">),</span> <span class="devsite-syntax-p">);</span> <span class="devsite-syntax-p">},</span> <span class="devsite-syntax-n">subtitleBuilder</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-p">(</span><span class="devsite-syntax-n">context</span><span class="devsite-syntax-p">,</span> <span class="devsite-syntax-n">action</span><span class="devsite-syntax-p">)</span> <span class="devsite-syntax-p">{</span> <span class="devsite-syntax-k">return</span> <span class="devsite-syntax-n">Padding</span><span class="devsite-syntax-p">(</span> <span class="devsite-syntax-n">padding</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-n">const</span> <span class="devsite-syntax-n">EdgeInsets</span><span class="devsite-syntax-o">.</span><span class="devsite-syntax-n">symmetric</span><span class="devsite-syntax-p">(</span><span class="devsite-syntax-n">vertical</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-mf">8.0</span><span class="devsite-syntax-p">),</span> <span class="devsite-syntax-n">child</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-n">action</span> <span class="devsite-syntax-o">==</span> <span class="devsite-syntax-n">AuthAction</span><span class="devsite-syntax-o">.</span><span class="devsite-syntax-n">signIn</span> <span class="devsite-syntax-err">?</span> <span class="devsite-syntax-n">const</span> <span class="devsite-syntax-n">Text</span><span class="devsite-syntax-p">(</span><span class="devsite-syntax-s1">'Welcome to FlutterFire, please sign in!'</span><span class="devsite-syntax-p">)</span> <span class="devsite-syntax-p">:</span> <span class="devsite-syntax-n">const</span> <span class="devsite-syntax-n">Text</span><span class="devsite-syntax-p">(</span><span class="devsite-syntax-s1">'Welcome to Flutterfire, please sign up!'</span><span class="devsite-syntax-p">),</span> <span class="devsite-syntax-p">);</span> <span class="devsite-syntax-p">},</span> <span class="devsite-syntax-n">footerBuilder</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-p">(</span><span class="devsite-syntax-n">context</span><span class="devsite-syntax-p">,</span> <span class="devsite-syntax-n">action</span><span class="devsite-syntax-p">)</span> <span class="devsite-syntax-p">{</span> <span class="devsite-syntax-k">return</span> <span class="devsite-syntax-n">const</span> <span class="devsite-syntax-n">Padding</span><span class="devsite-syntax-p">(</span> <span class="devsite-syntax-n">padding</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-n">EdgeInsets</span><span class="devsite-syntax-o">.</span><span class="devsite-syntax-n">only</span><span class="devsite-syntax-p">(</span><span class="devsite-syntax-n">top</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-mi">16</span><span class="devsite-syntax-p">),</span> <span class="devsite-syntax-n">child</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-n">Text</span><span class="devsite-syntax-p">(</span> <span class="devsite-syntax-s1">'By signing in, you agree to our terms and conditions.'</span><span class="devsite-syntax-p">,</span> <span class="devsite-syntax-n">style</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-n">TextStyle</span><span class="devsite-syntax-p">(</span><span class="devsite-syntax-n">color</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-n">Colors</span><span class="devsite-syntax-o">.</span><span class="devsite-syntax-n">grey</span><span class="devsite-syntax-p">),</span> <span class="devsite-syntax-p">),</span> <span class="devsite-syntax-p">);</span> <span class="devsite-syntax-p">},</span> <span class="devsite-syntax-p">);</span> <span class="devsite-syntax-p">}</span> <span class="devsite-syntax-k">return</span> <span class="devsite-syntax-n">const</span> <span class="devsite-syntax-n">HomeScreen</span><span class="devsite-syntax-p">();</span> <span class="devsite-syntax-p">},</span> <span class="devsite-syntax-p">);</span> <span class="devsite-syntax-p">}}</span> </code></pre></devsite-code> <h2 is-upgraded id="side-builder" data-text="Side Builder" tabindex="-1">Side Builder</h2> <p>The SignInScreen.sidebuilder argument accepts a callback, and this time the arguments to that callback are <code translate="no" dir="ltr">BuildContext</code> and <code translate="no" dir="ltr">double shrinkOffset</code>. The widget that sideBuilder returns will be displayed to the left of the sign in form, and only on wide screens. Effectively that means the widget will only be displayed on desktop and web apps.</p> <p>Internally, FlutterFire UI uses a breakpoint to determine if the header content should be shown (on tall screens, like mobile) or the side content should be shown (on wide screens, desktop or web). Specifically, if a screen is more than 800 pixels wide, the side builder content is shown, and the header content is not. If the screen is less than 800 pixels wide, the opposite is true.</p> <p>Update the code in auth_gate.dart to add sideBuilder widgets.</p> <h3 is-upgraded id="auth_gate.dart_5" data-text="auth_gate.dart" tabindex="-1"><a href="https://github.com/flutter/codelabs/firebase-auth-flutterfire-ui/complete/lib/auth_gate.dart" target="_blank">auth_gate.dart</a></h3> <div></div><devsite-code><pre class="devsite-click-to-copy" translate="no" dir="ltr" is-upgraded syntax="Python"><code language="language-dart" class="language-dart" translate="no" dir="ltr"><span class="devsite-syntax-kn">import</span> <span class="devsite-syntax-s1">'package:firebase_auth/firebase_auth.dart'</span> <span class="devsite-syntax-n">hide</span> <span class="devsite-syntax-n">EmailAuthProvider</span><span class="devsite-syntax-p">;</span> <span class="devsite-syntax-kn">import</span> <span class="devsite-syntax-s1">'package:firebase_ui_auth/firebase_ui_auth.dart'</span><span class="devsite-syntax-p">;</span> <span class="devsite-syntax-kn">import</span> <span class="devsite-syntax-s1">'package:flutter/material.dart'</span><span class="devsite-syntax-p">;</span> <span class="devsite-syntax-kn">import</span> <span class="devsite-syntax-s1">'home.dart'</span><span class="devsite-syntax-p">;</span> <span class="devsite-syntax-k">class</span> <span class="devsite-syntax-nc">AuthGate</span> <span class="devsite-syntax-n">extends</span> <span class="devsite-syntax-n">StatelessWidget</span> <span class="devsite-syntax-p">{</span> <span class="devsite-syntax-n">const</span> <span class="devsite-syntax-n">AuthGate</span><span class="devsite-syntax-p">({</span><span class="devsite-syntax-nb">super</span><span class="devsite-syntax-o">.</span><span class="devsite-syntax-n">key</span><span class="devsite-syntax-p">});</span> <span class="devsite-syntax-nd">@override</span> <span class="devsite-syntax-n">Widget</span> <span class="devsite-syntax-n">build</span><span class="devsite-syntax-p">(</span><span class="devsite-syntax-n">BuildContext</span> <span class="devsite-syntax-n">context</span><span class="devsite-syntax-p">)</span> <span class="devsite-syntax-p">{</span> <span class="devsite-syntax-k">return</span> <span class="devsite-syntax-n">StreamBuilder<User</span><span class="devsite-syntax-err">?</span>><span class="devsite-syntax-p">(</span> <span class="devsite-syntax-n">stream</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-n">FirebaseAuth</span><span class="devsite-syntax-o">.</span><span class="devsite-syntax-n">instance</span><span class="devsite-syntax-o">.</span><span class="devsite-syntax-n">authStateChanges</span><span class="devsite-syntax-p">(),</span> <span class="devsite-syntax-n">builder</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-p">(</span><span class="devsite-syntax-n">context</span><span class="devsite-syntax-p">,</span> <span class="devsite-syntax-n">snapshot</span><span class="devsite-syntax-p">)</span> <span class="devsite-syntax-p">{</span> <span class="devsite-syntax-k">if</span> <span class="devsite-syntax-p">(</span><span class="devsite-syntax-err">!</span><span class="devsite-syntax-n">snapshot</span><span class="devsite-syntax-o">.</span><span class="devsite-syntax-n">hasData</span><span class="devsite-syntax-p">)</span> <span class="devsite-syntax-p">{</span> <span class="devsite-syntax-k">return</span> <span class="devsite-syntax-n">SignInScreen</span><span class="devsite-syntax-p">(</span> <span class="devsite-syntax-n">providers</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-p">[</span> <span class="devsite-syntax-n">EmailAuthProvider</span><span class="devsite-syntax-p">(),</span> <span class="devsite-syntax-p">],</span> <span class="devsite-syntax-n">headerBuilder</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-p">(</span><span class="devsite-syntax-n">context</span><span class="devsite-syntax-p">,</span> <span class="devsite-syntax-n">constraints</span><span class="devsite-syntax-p">,</span> <span class="devsite-syntax-n">shrinkOffset</span><span class="devsite-syntax-p">)</span> <span class="devsite-syntax-p">{</span> <span class="devsite-syntax-k">return</span> <span class="devsite-syntax-n">Padding</span><span class="devsite-syntax-p">(</span> <span class="devsite-syntax-n">padding</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-n">const</span> <span class="devsite-syntax-n">EdgeInsets</span><span class="devsite-syntax-o">.</span><span class="devsite-syntax-n">all</span><span class="devsite-syntax-p">(</span><span class="devsite-syntax-mi">20</span><span class="devsite-syntax-p">),</span> <span class="devsite-syntax-n">child</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-n">AspectRatio</span><span class="devsite-syntax-p">(</span> <span class="devsite-syntax-n">aspectRatio</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-mi">1</span><span class="devsite-syntax-p">,</span> <span class="devsite-syntax-n">child</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-n">Image</span><span class="devsite-syntax-o">.</span><span class="devsite-syntax-n">asset</span><span class="devsite-syntax-p">(</span><span class="devsite-syntax-s1">'flutterfire_300x.png'</span><span class="devsite-syntax-p">),</span> <span class="devsite-syntax-p">),</span> <span class="devsite-syntax-p">);</span> <span class="devsite-syntax-p">},</span> <span class="devsite-syntax-n">subtitleBuilder</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-p">(</span><span class="devsite-syntax-n">context</span><span class="devsite-syntax-p">,</span> <span class="devsite-syntax-n">action</span><span class="devsite-syntax-p">)</span> <span class="devsite-syntax-p">{</span> <span class="devsite-syntax-k">return</span> <span class="devsite-syntax-n">Padding</span><span class="devsite-syntax-p">(</span> <span class="devsite-syntax-n">padding</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-n">const</span> <span class="devsite-syntax-n">EdgeInsets</span><span class="devsite-syntax-o">.</span><span class="devsite-syntax-n">symmetric</span><span class="devsite-syntax-p">(</span><span class="devsite-syntax-n">vertical</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-mf">8.0</span><span class="devsite-syntax-p">),</span> <span class="devsite-syntax-n">child</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-n">action</span> <span class="devsite-syntax-o">==</span> <span class="devsite-syntax-n">AuthAction</span><span class="devsite-syntax-o">.</span><span class="devsite-syntax-n">signIn</span> <span class="devsite-syntax-err">?</span> <span class="devsite-syntax-n">const</span> <span class="devsite-syntax-n">Text</span><span class="devsite-syntax-p">(</span><span class="devsite-syntax-s1">'Welcome to FlutterFire, please sign in!'</span><span class="devsite-syntax-p">)</span> <span class="devsite-syntax-p">:</span> <span class="devsite-syntax-n">const</span> <span class="devsite-syntax-n">Text</span><span class="devsite-syntax-p">(</span><span class="devsite-syntax-s1">'Welcome to Flutterfire, please sign up!'</span><span class="devsite-syntax-p">),</span> <span class="devsite-syntax-p">);</span> <span class="devsite-syntax-p">},</span> <span class="devsite-syntax-n">footerBuilder</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-p">(</span><span class="devsite-syntax-n">context</span><span class="devsite-syntax-p">,</span> <span class="devsite-syntax-n">action</span><span class="devsite-syntax-p">)</span> <span class="devsite-syntax-p">{</span> <span class="devsite-syntax-k">return</span> <span class="devsite-syntax-n">const</span> <span class="devsite-syntax-n">Padding</span><span class="devsite-syntax-p">(</span> <span class="devsite-syntax-n">padding</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-n">EdgeInsets</span><span class="devsite-syntax-o">.</span><span class="devsite-syntax-n">only</span><span class="devsite-syntax-p">(</span><span class="devsite-syntax-n">top</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-mi">16</span><span class="devsite-syntax-p">),</span> <span class="devsite-syntax-n">child</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-n">Text</span><span class="devsite-syntax-p">(</span> <span class="devsite-syntax-s1">'By signing in, you agree to our terms and conditions.'</span><span class="devsite-syntax-p">,</span> <span class="devsite-syntax-n">style</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-n">TextStyle</span><span class="devsite-syntax-p">(</span><span class="devsite-syntax-n">color</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-n">Colors</span><span class="devsite-syntax-o">.</span><span class="devsite-syntax-n">grey</span><span class="devsite-syntax-p">),</span> <span class="devsite-syntax-p">),</span> <span class="devsite-syntax-p">);</span> <span class="devsite-syntax-p">},</span> <span class="devsite-syntax-n">sideBuilder</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-p">(</span><span class="devsite-syntax-n">context</span><span class="devsite-syntax-p">,</span> <span class="devsite-syntax-n">shrinkOffset</span><span class="devsite-syntax-p">)</span> <span class="devsite-syntax-p">{</span> <span class="devsite-syntax-k">return</span> <span class="devsite-syntax-n">Padding</span><span class="devsite-syntax-p">(</span> <span class="devsite-syntax-n">padding</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-n">const</span> <span class="devsite-syntax-n">EdgeInsets</span><span class="devsite-syntax-o">.</span><span class="devsite-syntax-n">all</span><span class="devsite-syntax-p">(</span><span class="devsite-syntax-mi">20</span><span class="devsite-syntax-p">),</span> <span class="devsite-syntax-n">child</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-n">AspectRatio</span><span class="devsite-syntax-p">(</span> <span class="devsite-syntax-n">aspectRatio</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-mi">1</span><span class="devsite-syntax-p">,</span> <span class="devsite-syntax-n">child</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-n">Image</span><span class="devsite-syntax-o">.</span><span class="devsite-syntax-n">asset</span><span class="devsite-syntax-p">(</span><span class="devsite-syntax-s1">'flutterfire_300x.png'</span><span class="devsite-syntax-p">),</span> <span class="devsite-syntax-p">),</span> <span class="devsite-syntax-p">);</span> <span class="devsite-syntax-p">},</span> <span class="devsite-syntax-p">);</span> <span class="devsite-syntax-p">}</span> <span class="devsite-syntax-k">return</span> <span class="devsite-syntax-n">const</span> <span class="devsite-syntax-n">HomeScreen</span><span class="devsite-syntax-p">();</span> <span class="devsite-syntax-p">},</span> <span class="devsite-syntax-p">);</span> <span class="devsite-syntax-p">}</span> <span class="devsite-syntax-p">}</span> </code></pre></devsite-code> <p>Your app should now look like this when you expand the width of the window (if you're using Flutter web or MacOS).</p> <p class="image-container"><img alt="8dc60b4e5d7dd2d0.png" style="width: 624.00px" src="/static/codelabs/firebase-auth-in-flutter-apps/img/8dc60b4e5d7dd2d0.png" srcset="https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/8dc60b4e5d7dd2d0_36.png 36w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/8dc60b4e5d7dd2d0_48.png 48w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/8dc60b4e5d7dd2d0_72.png 72w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/8dc60b4e5d7dd2d0_96.png 96w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/8dc60b4e5d7dd2d0_480.png 480w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/8dc60b4e5d7dd2d0_720.png 720w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/8dc60b4e5d7dd2d0_856.png 856w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/8dc60b4e5d7dd2d0_960.png 960w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/8dc60b4e5d7dd2d0_1440.png 1440w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/8dc60b4e5d7dd2d0_1920.png 1920w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/8dc60b4e5d7dd2d0_2880.png 2880w" sizes="(max-width: 840px) 100vw, 856px"></p> <h2 is-upgraded id="create-a-user" data-text="Create a user" tabindex="-1">Create a user</h2> <p>At this point, all of the code for this screen is done. Before you can sign-in, though, you need to create a User. You can do this with the "Register" screen, or you can create a user in the Firebase console.</p> <p>To use the console:</p> <ol type="1"> <li>Go to the "Users" table in the Firebase console.</li> <li><a href="https://console.firebase.google.com/project/_/authentication/users" target="_blank">Click here</a></li> <li>Select ‘flutterfire-ui-codelab' (or another project if you used a different name). You'll see this table:</li> </ol> <p class="image-container"><img alt="f038fd9a58ed60d9.png" style="width: 624.00px" src="/static/codelabs/firebase-auth-in-flutter-apps/img/f038fd9a58ed60d9.png" srcset="https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/f038fd9a58ed60d9_36.png 36w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/f038fd9a58ed60d9_48.png 48w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/f038fd9a58ed60d9_72.png 72w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/f038fd9a58ed60d9_96.png 96w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/f038fd9a58ed60d9_480.png 480w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/f038fd9a58ed60d9_720.png 720w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/f038fd9a58ed60d9_856.png 856w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/f038fd9a58ed60d9_960.png 960w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/f038fd9a58ed60d9_1440.png 1440w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/f038fd9a58ed60d9_1920.png 1920w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/f038fd9a58ed60d9_2880.png 2880w" sizes="(max-width: 840px) 100vw, 856px"></p> <ol type="1" start="2"> <li>Click the "Add user" button.</li> </ol> <p class="image-container"><img alt="2d78390d4c5dbbfa.png" style="width: 624.00px" src="/static/codelabs/firebase-auth-in-flutter-apps/img/2d78390d4c5dbbfa.png" srcset="https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/2d78390d4c5dbbfa_36.png 36w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/2d78390d4c5dbbfa_48.png 48w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/2d78390d4c5dbbfa_72.png 72w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/2d78390d4c5dbbfa_96.png 96w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/2d78390d4c5dbbfa_480.png 480w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/2d78390d4c5dbbfa_720.png 720w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/2d78390d4c5dbbfa_856.png 856w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/2d78390d4c5dbbfa_960.png 960w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/2d78390d4c5dbbfa_1440.png 1440w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/2d78390d4c5dbbfa_1920.png 1920w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/2d78390d4c5dbbfa_2880.png 2880w" sizes="(max-width: 840px) 100vw, 856px"></p> <ol type="1" start="3"> <li>Enter an email address and password for the new user. This can be a fake email and password, as I've entered in the image below. That will work, but the "Forgot password" functionality will not work if you use a fake email address.</li> </ol> <p class="image-container"><img alt="62ba0feb33d54add.png" style="width: 624.00px" src="/static/codelabs/firebase-auth-in-flutter-apps/img/62ba0feb33d54add.png" srcset="https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/62ba0feb33d54add_36.png 36w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/62ba0feb33d54add_48.png 48w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/62ba0feb33d54add_72.png 72w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/62ba0feb33d54add_96.png 96w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/62ba0feb33d54add_480.png 480w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/62ba0feb33d54add_720.png 720w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/62ba0feb33d54add_856.png 856w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/62ba0feb33d54add_960.png 960w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/62ba0feb33d54add_1440.png 1440w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/62ba0feb33d54add_1920.png 1920w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/62ba0feb33d54add_2880.png 2880w" sizes="(max-width: 840px) 100vw, 856px"></p> <ol type="1" start="4"> <li>Click "Add user"</li> </ol> <p class="image-container"><img alt="32b236b3ef94d4c7.png" style="width: 624.00px" src="/static/codelabs/firebase-auth-in-flutter-apps/img/32b236b3ef94d4c7.png" srcset="https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/32b236b3ef94d4c7_36.png 36w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/32b236b3ef94d4c7_48.png 48w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/32b236b3ef94d4c7_72.png 72w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/32b236b3ef94d4c7_96.png 96w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/32b236b3ef94d4c7_480.png 480w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/32b236b3ef94d4c7_720.png 720w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/32b236b3ef94d4c7_856.png 856w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/32b236b3ef94d4c7_960.png 960w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/32b236b3ef94d4c7_1440.png 1440w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/32b236b3ef94d4c7_1920.png 1920w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/32b236b3ef94d4c7_2880.png 2880w" sizes="(max-width: 840px) 100vw, 856px"></p> <p>Now, you can return to your Flutter application, and sign in a user via the sign-in page. Your app should look like this:</p> <p class="image-container"><img alt="dd43d260537f3b1a.png" style="width: 288.00px" src="/static/codelabs/firebase-auth-in-flutter-apps/img/dd43d260537f3b1a.png" srcset="https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/dd43d260537f3b1a_36.png 36w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/dd43d260537f3b1a_48.png 48w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/dd43d260537f3b1a_72.png 72w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/dd43d260537f3b1a_96.png 96w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/dd43d260537f3b1a_480.png 480w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/dd43d260537f3b1a_720.png 720w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/dd43d260537f3b1a_856.png 856w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/dd43d260537f3b1a_960.png 960w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/dd43d260537f3b1a_1440.png 1440w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/dd43d260537f3b1a_1920.png 1920w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/dd43d260537f3b1a_2880.png 2880w" sizes="(max-width: 840px) 100vw, 856px"></p> </google-codelab-step> <google-codelab-step label="Profile Screen" duration="0" step="5"> <h2 class="step-title" id="5" data-text="Profile Screen" tabindex="-1"> 6. Profile Screen </h2> <p>FlutterFire UI also provides a <code translate="no" dir="ltr">ProfileScreen</code> widget, which again, gives you a lot of functionality in a few lines of code.</p> <h2 is-upgraded id="add-profilescreen-widget" data-text="Add ProfileScreen widget" tabindex="-1">Add ProfileScreen widget</h2> <p>Navigate to the <code translate="no" dir="ltr">home.dart</code> file in your text editor. Update it with this code:</p> <h3 is-upgraded id="home.dart" data-text="home.dart" tabindex="-1"><a href="https://github.com/flutter/codelabs/firebase-auth-flutterfire-ui/complete/lib/home.dart" target="_blank">home.dart</a></h3> <div></div><devsite-code><pre class="devsite-click-to-copy" translate="no" dir="ltr" is-upgraded syntax="Python"><code language="language-dart" class="language-dart" translate="no" dir="ltr"><span class="devsite-syntax-kn">import</span> <span class="devsite-syntax-s1">'package:firebase_ui_auth/firebase_ui_auth.dart'</span><span class="devsite-syntax-p">;</span> <span class="devsite-syntax-kn">import</span> <span class="devsite-syntax-s1">'package:flutter/material.dart'</span><span class="devsite-syntax-p">;</span> <span class="devsite-syntax-k">class</span> <span class="devsite-syntax-nc">HomeScreen</span> <span class="devsite-syntax-n">extends</span> <span class="devsite-syntax-n">StatelessWidget</span> <span class="devsite-syntax-p">{</span> <span class="devsite-syntax-n">const</span> <span class="devsite-syntax-n">HomeScreen</span><span class="devsite-syntax-p">({</span><span class="devsite-syntax-nb">super</span><span class="devsite-syntax-o">.</span><span class="devsite-syntax-n">key</span><span class="devsite-syntax-p">});</span> <span class="devsite-syntax-nd">@override</span> <span class="devsite-syntax-n">Widget</span> <span class="devsite-syntax-n">build</span><span class="devsite-syntax-p">(</span><span class="devsite-syntax-n">BuildContext</span> <span class="devsite-syntax-n">context</span><span class="devsite-syntax-p">)</span> <span class="devsite-syntax-p">{</span> <span class="devsite-syntax-k">return</span> <span class="devsite-syntax-n">Scaffold</span><span class="devsite-syntax-p">(</span> <span class="devsite-syntax-n">appBar</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-n">AppBar</span><span class="devsite-syntax-p">(</span> <span class="devsite-syntax-n">actions</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-p">[</span> <span class="devsite-syntax-n">IconButton</span><span class="devsite-syntax-p">(</span> <span class="devsite-syntax-n">icon</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-n">const</span> <span class="devsite-syntax-n">Icon</span><span class="devsite-syntax-p">(</span><span class="devsite-syntax-n">Icons</span><span class="devsite-syntax-o">.</span><span class="devsite-syntax-n">person</span><span class="devsite-syntax-p">),</span> <span class="devsite-syntax-n">onPressed</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-p">()</span> <span class="devsite-syntax-p">{</span> <span class="devsite-syntax-n">Navigator</span><span class="devsite-syntax-o">.</span><span class="devsite-syntax-n">push</span><span class="devsite-syntax-p">(</span> <span class="devsite-syntax-n">context</span><span class="devsite-syntax-p">,</span> <span class="devsite-syntax-n">MaterialPageRoute<ProfileScreen></span><span class="devsite-syntax-p">(</span> <span class="devsite-syntax-n">builder</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-p">(</span><span class="devsite-syntax-n">context</span><span class="devsite-syntax-p">)</span> <span class="devsite-syntax-o">=</span>> <span class="devsite-syntax-n">const</span> <span class="devsite-syntax-n">ProfileScreen</span><span class="devsite-syntax-p">(),</span> <span class="devsite-syntax-p">),</span> <span class="devsite-syntax-p">);</span> <span class="devsite-syntax-p">},</span> <span class="devsite-syntax-p">)</span> <span class="devsite-syntax-p">],</span> <span class="devsite-syntax-n">automaticallyImplyLeading</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-n">false</span><span class="devsite-syntax-p">,</span> <span class="devsite-syntax-p">),</span> <span class="devsite-syntax-n">body</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-n">Center</span><span class="devsite-syntax-p">(</span> <span class="devsite-syntax-n">child</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-n">Column</span><span class="devsite-syntax-p">(</span> <span class="devsite-syntax-n">children</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-p">[</span> <span class="devsite-syntax-n">Image</span><span class="devsite-syntax-o">.</span><span class="devsite-syntax-n">asset</span><span class="devsite-syntax-p">(</span><span class="devsite-syntax-s1">'dash.png'</span><span class="devsite-syntax-p">),</span> <span class="devsite-syntax-n">Text</span><span class="devsite-syntax-p">(</span> <span class="devsite-syntax-s1">'Welcome!'</span><span class="devsite-syntax-p">,</span> <span class="devsite-syntax-n">style</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-n">Theme</span><span class="devsite-syntax-o">.</span><span class="devsite-syntax-n">of</span><span class="devsite-syntax-p">(</span><span class="devsite-syntax-n">context</span><span class="devsite-syntax-p">)</span><span class="devsite-syntax-o">.</span><span class="devsite-syntax-n">textTheme</span><span class="devsite-syntax-o">.</span><span class="devsite-syntax-n">displaySmall</span><span class="devsite-syntax-p">,</span> <span class="devsite-syntax-p">),</span> <span class="devsite-syntax-n">const</span> <span class="devsite-syntax-n">SignOutButton</span><span class="devsite-syntax-p">(),</span> <span class="devsite-syntax-p">],</span> <span class="devsite-syntax-p">),</span> <span class="devsite-syntax-p">),</span> <span class="devsite-syntax-p">);</span> <span class="devsite-syntax-p">}</span> <span class="devsite-syntax-p">}</span> </code></pre></devsite-code> <p>The new code of note is the callback passed to the <code translate="no" dir="ltr">IconButton.isPressed method.</code> When that <code translate="no" dir="ltr">IconButton</code> is pressed, your application creates a new anonymous route and navigates to it. That route will display the <code translate="no" dir="ltr">ProfileScreen</code> widget, which is returned from the <code translate="no" dir="ltr">MaterialPageRoute.builder</code> callback.</p> <p>Reload your app, and push the icon in the top-right (in the app bar), and it will display a page like this:</p> <p class="image-container"><img alt="36487fc4ab4f26a7.png" style="width: 269.50px" src="/static/codelabs/firebase-auth-in-flutter-apps/img/36487fc4ab4f26a7.png" srcset="https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/36487fc4ab4f26a7_36.png 36w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/36487fc4ab4f26a7_48.png 48w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/36487fc4ab4f26a7_72.png 72w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/36487fc4ab4f26a7_96.png 96w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/36487fc4ab4f26a7_480.png 480w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/36487fc4ab4f26a7_720.png 720w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/36487fc4ab4f26a7_856.png 856w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/36487fc4ab4f26a7_960.png 960w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/36487fc4ab4f26a7_1440.png 1440w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/36487fc4ab4f26a7_1920.png 1920w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/36487fc4ab4f26a7_2880.png 2880w" sizes="(max-width: 840px) 100vw, 856px"></p> <p>This is the standard UI provided by the FlutterFire UI page. All of the buttons and text fields are wired up to Firebase Auth, and work out of the box. For example, you can enter a name into the "Name" textfield, and FlutterFire UI will call the <code translate="no" dir="ltr">FirebaseAuth.instance.currentUser?.updateDisplayName</code> method, which will save that name in Firebase.</p> <aside class="special"><p><strong>Note</strong>: In this example, the "Send verification email" button will send an email to a fake email address - <a href="mailto:dash@email.com" target="_blank">dash@email.com</a>. To verify that it works, create a user with an email address you own.</p> </aside> <h2 is-upgraded id="signing-out" data-text="Signing Out" tabindex="-1">Signing Out</h2> <p>Right now, if you press the "Sign out" button, the app will not change. It will sign you out, but you will not be navigated back to the AuthGate widget. To implement this, use the ProfileScreen.actions parameter.</p> <p>First, update the code in home.dart.</p> <h3 is-upgraded id="home.dart_1" data-text="home.dart" tabindex="-1"><a href="https://github.com/flutter/codelabs/firebase-auth-flutterfire-ui/complete/lib/home.dart" target="_blank">home.dart</a></h3> <div></div><devsite-code><pre class="devsite-click-to-copy" translate="no" dir="ltr" is-upgraded syntax="Python"><code language="language-dart" class="language-dart" translate="no" dir="ltr"><span class="devsite-syntax-kn">import</span> <span class="devsite-syntax-s1">'package:firebase_ui_auth/firebase_ui_auth.dart'</span><span class="devsite-syntax-p">;</span> <span class="devsite-syntax-kn">import</span> <span class="devsite-syntax-s1">'package:flutter/material.dart'</span><span class="devsite-syntax-p">;</span> <span class="devsite-syntax-k">class</span> <span class="devsite-syntax-nc">HomeScreen</span> <span class="devsite-syntax-n">extends</span> <span class="devsite-syntax-n">StatelessWidget</span> <span class="devsite-syntax-p">{</span> <span class="devsite-syntax-n">const</span> <span class="devsite-syntax-n">HomeScreen</span><span class="devsite-syntax-p">({</span><span class="devsite-syntax-nb">super</span><span class="devsite-syntax-o">.</span><span class="devsite-syntax-n">key</span><span class="devsite-syntax-p">});</span> <span class="devsite-syntax-nd">@override</span> <span class="devsite-syntax-n">Widget</span> <span class="devsite-syntax-n">build</span><span class="devsite-syntax-p">(</span><span class="devsite-syntax-n">BuildContext</span> <span class="devsite-syntax-n">context</span><span class="devsite-syntax-p">)</span> <span class="devsite-syntax-p">{</span> <span class="devsite-syntax-k">return</span> <span class="devsite-syntax-n">Scaffold</span><span class="devsite-syntax-p">(</span> <span class="devsite-syntax-n">appBar</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-n">AppBar</span><span class="devsite-syntax-p">(</span> <span class="devsite-syntax-n">actions</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-p">[</span> <span class="devsite-syntax-n">IconButton</span><span class="devsite-syntax-p">(</span> <span class="devsite-syntax-n">icon</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-n">const</span> <span class="devsite-syntax-n">Icon</span><span class="devsite-syntax-p">(</span><span class="devsite-syntax-n">Icons</span><span class="devsite-syntax-o">.</span><span class="devsite-syntax-n">person</span><span class="devsite-syntax-p">),</span> <span class="devsite-syntax-n">onPressed</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-p">()</span> <span class="devsite-syntax-p">{</span> <span class="devsite-syntax-n">Navigator</span><span class="devsite-syntax-o">.</span><span class="devsite-syntax-n">push</span><span class="devsite-syntax-p">(</span> <span class="devsite-syntax-n">context</span><span class="devsite-syntax-p">,</span> <span class="devsite-syntax-n">MaterialPageRoute<ProfileScreen></span><span class="devsite-syntax-p">(</span> <span class="devsite-syntax-n">builder</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-p">(</span><span class="devsite-syntax-n">context</span><span class="devsite-syntax-p">)</span> <span class="devsite-syntax-o">=</span>> <span class="devsite-syntax-n">ProfileScreen</span><span class="devsite-syntax-p">(</span> <span class="devsite-syntax-n">actions</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-p">[</span> <span class="devsite-syntax-n">SignedOutAction</span><span class="devsite-syntax-p">((</span><span class="devsite-syntax-n">context</span><span class="devsite-syntax-p">)</span> <span class="devsite-syntax-p">{</span> <span class="devsite-syntax-n">Navigator</span><span class="devsite-syntax-o">.</span><span class="devsite-syntax-n">of</span><span class="devsite-syntax-p">(</span><span class="devsite-syntax-n">context</span><span class="devsite-syntax-p">)</span><span class="devsite-syntax-o">.</span><span class="devsite-syntax-n">pop</span><span class="devsite-syntax-p">();</span> <span class="devsite-syntax-p">})</span> <span class="devsite-syntax-p">],</span> <span class="devsite-syntax-p">),</span> <span class="devsite-syntax-p">),</span> <span class="devsite-syntax-p">);</span> <span class="devsite-syntax-p">},</span> <span class="devsite-syntax-p">)</span> <span class="devsite-syntax-p">],</span> <span class="devsite-syntax-n">automaticallyImplyLeading</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-n">false</span><span class="devsite-syntax-p">,</span> <span class="devsite-syntax-p">),</span> <span class="devsite-syntax-n">body</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-n">Center</span><span class="devsite-syntax-p">(</span> <span class="devsite-syntax-n">child</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-n">Column</span><span class="devsite-syntax-p">(</span> <span class="devsite-syntax-n">children</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-p">[</span> <span class="devsite-syntax-n">Image</span><span class="devsite-syntax-o">.</span><span class="devsite-syntax-n">asset</span><span class="devsite-syntax-p">(</span><span class="devsite-syntax-s1">'dash.png'</span><span class="devsite-syntax-p">),</span> <span class="devsite-syntax-n">Text</span><span class="devsite-syntax-p">(</span> <span class="devsite-syntax-s1">'Welcome!'</span><span class="devsite-syntax-p">,</span> <span class="devsite-syntax-n">style</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-n">Theme</span><span class="devsite-syntax-o">.</span><span class="devsite-syntax-n">of</span><span class="devsite-syntax-p">(</span><span class="devsite-syntax-n">context</span><span class="devsite-syntax-p">)</span><span class="devsite-syntax-o">.</span><span class="devsite-syntax-n">textTheme</span><span class="devsite-syntax-o">.</span><span class="devsite-syntax-n">displaySmall</span><span class="devsite-syntax-p">,</span> <span class="devsite-syntax-p">),</span> <span class="devsite-syntax-n">const</span> <span class="devsite-syntax-n">SignOutButton</span><span class="devsite-syntax-p">(),</span> <span class="devsite-syntax-p">],</span> <span class="devsite-syntax-p">),</span> <span class="devsite-syntax-p">),</span> <span class="devsite-syntax-p">);</span> <span class="devsite-syntax-p">}</span> <span class="devsite-syntax-p">}</span> </code></pre></devsite-code> <p>Now, when you create an instance of <code translate="no" dir="ltr">ProfileScreen</code>, you also pass it a list of actions to the <code translate="no" dir="ltr">ProfileScreen.actions</code> argument. These actions are of the type <code translate="no" dir="ltr">FlutterFireUiAction</code>. There are many different classes that are subtypes of <code translate="no" dir="ltr">FlutterFireUiAction</code>, and in general you use them to tell your app to react to different auth state changes. The SignedOutAction calls a callback function that you give it when the Firebase auth state changes to the currentUser being null.</p> <p>By adding a callback that calls <code translate="no" dir="ltr">Navigator.of(context).pop()</code> when SignedOutAction triggers, the app will navigate to the previous page. In this example app, there is only one permanent route, which shows the sign in page if there isn't a user signed in, and the home page if there is a user. Because this happens when the user signs out, the app will display the SignIn page.</p> <h2 is-upgraded id="customize-the-profile-page" data-text="Customize the Profile Page" tabindex="-1">Customize the Profile Page</h2> <p>Similar to the Sign In page, the profile page is customizable. First, our current page has no way of navigating back to the home page once a user is on the profile page. Fix this by giving the ProfileScreen widget an AppBar.</p> <h3 is-upgraded id="home.dart_2" data-text="home.dart" tabindex="-1"><a href="https://github.com/flutter/codelabs/firebase-auth-flutterfire-ui/complete/lib/home.dart" target="_blank">home.dart</a></h3> <div></div><devsite-code><pre class="devsite-click-to-copy" translate="no" dir="ltr" is-upgraded syntax="Python"><code language="language-dart" class="language-dart" translate="no" dir="ltr"><span class="devsite-syntax-kn">import</span> <span class="devsite-syntax-s1">'package:firebase_ui_auth/firebase_ui_auth.dart'</span><span class="devsite-syntax-p">;</span> <span class="devsite-syntax-kn">import</span> <span class="devsite-syntax-s1">'package:flutter/material.dart'</span><span class="devsite-syntax-p">;</span> <span class="devsite-syntax-k">class</span> <span class="devsite-syntax-nc">HomeScreen</span> <span class="devsite-syntax-n">extends</span> <span class="devsite-syntax-n">StatelessWidget</span> <span class="devsite-syntax-p">{</span> <span class="devsite-syntax-n">const</span> <span class="devsite-syntax-n">HomeScreen</span><span class="devsite-syntax-p">({</span><span class="devsite-syntax-nb">super</span><span class="devsite-syntax-o">.</span><span class="devsite-syntax-n">key</span><span class="devsite-syntax-p">});</span> <span class="devsite-syntax-nd">@override</span> <span class="devsite-syntax-n">Widget</span> <span class="devsite-syntax-n">build</span><span class="devsite-syntax-p">(</span><span class="devsite-syntax-n">BuildContext</span> <span class="devsite-syntax-n">context</span><span class="devsite-syntax-p">)</span> <span class="devsite-syntax-p">{</span> <span class="devsite-syntax-k">return</span> <span class="devsite-syntax-n">Scaffold</span><span class="devsite-syntax-p">(</span> <span class="devsite-syntax-n">appBar</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-n">AppBar</span><span class="devsite-syntax-p">(</span> <span class="devsite-syntax-n">actions</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-p">[</span> <span class="devsite-syntax-n">IconButton</span><span class="devsite-syntax-p">(</span> <span class="devsite-syntax-n">icon</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-n">const</span> <span class="devsite-syntax-n">Icon</span><span class="devsite-syntax-p">(</span><span class="devsite-syntax-n">Icons</span><span class="devsite-syntax-o">.</span><span class="devsite-syntax-n">person</span><span class="devsite-syntax-p">),</span> <span class="devsite-syntax-n">onPressed</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-p">()</span> <span class="devsite-syntax-p">{</span> <span class="devsite-syntax-n">Navigator</span><span class="devsite-syntax-o">.</span><span class="devsite-syntax-n">push</span><span class="devsite-syntax-p">(</span> <span class="devsite-syntax-n">context</span><span class="devsite-syntax-p">,</span> <span class="devsite-syntax-n">MaterialPageRoute<ProfileScreen></span><span class="devsite-syntax-p">(</span> <span class="devsite-syntax-n">builder</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-p">(</span><span class="devsite-syntax-n">context</span><span class="devsite-syntax-p">)</span> <span class="devsite-syntax-o">=</span>> <span class="devsite-syntax-n">ProfileScreen</span><span class="devsite-syntax-p">(</span> <span class="devsite-syntax-n">appBar</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-n">AppBar</span><span class="devsite-syntax-p">(</span> <span class="devsite-syntax-n">title</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-n">const</span> <span class="devsite-syntax-n">Text</span><span class="devsite-syntax-p">(</span><span class="devsite-syntax-s1">'User Profile'</span><span class="devsite-syntax-p">),</span> <span class="devsite-syntax-p">),</span> <span class="devsite-syntax-n">actions</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-p">[</span> <span class="devsite-syntax-n">SignedOutAction</span><span class="devsite-syntax-p">((</span><span class="devsite-syntax-n">context</span><span class="devsite-syntax-p">)</span> <span class="devsite-syntax-p">{</span> <span class="devsite-syntax-n">Navigator</span><span class="devsite-syntax-o">.</span><span class="devsite-syntax-n">of</span><span class="devsite-syntax-p">(</span><span class="devsite-syntax-n">context</span><span class="devsite-syntax-p">)</span><span class="devsite-syntax-o">.</span><span class="devsite-syntax-n">pop</span><span class="devsite-syntax-p">();</span> <span class="devsite-syntax-p">})</span> <span class="devsite-syntax-p">],</span> <span class="devsite-syntax-p">),</span> <span class="devsite-syntax-p">),</span> <span class="devsite-syntax-p">);</span> <span class="devsite-syntax-p">},</span> <span class="devsite-syntax-p">)</span> <span class="devsite-syntax-p">],</span> <span class="devsite-syntax-n">automaticallyImplyLeading</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-n">false</span><span class="devsite-syntax-p">,</span> <span class="devsite-syntax-p">),</span> <span class="devsite-syntax-n">body</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-n">Center</span><span class="devsite-syntax-p">(</span> <span class="devsite-syntax-n">child</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-n">Column</span><span class="devsite-syntax-p">(</span> <span class="devsite-syntax-n">children</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-p">[</span> <span class="devsite-syntax-n">Image</span><span class="devsite-syntax-o">.</span><span class="devsite-syntax-n">asset</span><span class="devsite-syntax-p">(</span><span class="devsite-syntax-s1">'dash.png'</span><span class="devsite-syntax-p">),</span> <span class="devsite-syntax-n">Text</span><span class="devsite-syntax-p">(</span> <span class="devsite-syntax-s1">'Welcome!'</span><span class="devsite-syntax-p">,</span> <span class="devsite-syntax-n">style</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-n">Theme</span><span class="devsite-syntax-o">.</span><span class="devsite-syntax-n">of</span><span class="devsite-syntax-p">(</span><span class="devsite-syntax-n">context</span><span class="devsite-syntax-p">)</span><span class="devsite-syntax-o">.</span><span class="devsite-syntax-n">textTheme</span><span class="devsite-syntax-o">.</span><span class="devsite-syntax-n">displaySmall</span><span class="devsite-syntax-p">,</span> <span class="devsite-syntax-p">),</span> <span class="devsite-syntax-n">const</span> <span class="devsite-syntax-n">SignOutButton</span><span class="devsite-syntax-p">(),</span> <span class="devsite-syntax-p">],</span> <span class="devsite-syntax-p">),</span> <span class="devsite-syntax-p">),</span> <span class="devsite-syntax-p">);</span> <span class="devsite-syntax-p">}</span> <span class="devsite-syntax-p">}</span> </code></pre></devsite-code> <p>The <code translate="no" dir="ltr">ProfileScreen.appBar</code> argument accepts an <code translate="no" dir="ltr">AppBar</code> widget from the Flutter Material package, so it can be treated like any other <code translate="no" dir="ltr">AppBar</code> you've built and passed to a <code translate="no" dir="ltr">Scaffold</code>. In this example, the default functionality of automatically adding a "back" button is kept, and the screen now has a title.</p> <h3 is-upgraded id="add-children-to-the-profile-screen" data-text="Add Children to the Profile Screen" tabindex="-1">Add Children to the Profile Screen</h3> <p>The ProfileScreen widget also has an optional argument named children. This argument accepts a list of widgets, and those widgets will be placed vertically inside of a Column widget that's already used internally to build the ProfileScreen. This Column widget in the ProfileScreen build method will place the children you pass it above the "Sign out" button.</p> <p>Update the code in home.dart to show the company logo here, similar to the sign in screen.</p> <h3 is-upgraded id="home.dart_3" data-text="home.dart" tabindex="-1"><a href="https://github.com/flutter/codelabs/firebase-auth-flutterfire-ui/complete/lib/home.dart" target="_blank">home.dart</a></h3> <div></div><devsite-code><pre class="devsite-click-to-copy" translate="no" dir="ltr" is-upgraded syntax="Python"><code language="language-dart" class="language-dart" translate="no" dir="ltr"><span class="devsite-syntax-kn">import</span> <span class="devsite-syntax-s1">'package:firebase_ui_auth/firebase_ui_auth.dart'</span><span class="devsite-syntax-p">;</span> <span class="devsite-syntax-kn">import</span> <span class="devsite-syntax-s1">'package:flutter/material.dart'</span><span class="devsite-syntax-p">;</span> <span class="devsite-syntax-k">class</span> <span class="devsite-syntax-nc">HomeScreen</span> <span class="devsite-syntax-n">extends</span> <span class="devsite-syntax-n">StatelessWidget</span> <span class="devsite-syntax-p">{</span> <span class="devsite-syntax-n">const</span> <span class="devsite-syntax-n">HomeScreen</span><span class="devsite-syntax-p">({</span><span class="devsite-syntax-nb">super</span><span class="devsite-syntax-o">.</span><span class="devsite-syntax-n">key</span><span class="devsite-syntax-p">});</span> <span class="devsite-syntax-nd">@override</span> <span class="devsite-syntax-n">Widget</span> <span class="devsite-syntax-n">build</span><span class="devsite-syntax-p">(</span><span class="devsite-syntax-n">BuildContext</span> <span class="devsite-syntax-n">context</span><span class="devsite-syntax-p">)</span> <span class="devsite-syntax-p">{</span> <span class="devsite-syntax-k">return</span> <span class="devsite-syntax-n">Scaffold</span><span class="devsite-syntax-p">(</span> <span class="devsite-syntax-n">appBar</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-n">AppBar</span><span class="devsite-syntax-p">(</span> <span class="devsite-syntax-n">actions</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-p">[</span> <span class="devsite-syntax-n">IconButton</span><span class="devsite-syntax-p">(</span> <span class="devsite-syntax-n">icon</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-n">const</span> <span class="devsite-syntax-n">Icon</span><span class="devsite-syntax-p">(</span><span class="devsite-syntax-n">Icons</span><span class="devsite-syntax-o">.</span><span class="devsite-syntax-n">person</span><span class="devsite-syntax-p">),</span> <span class="devsite-syntax-n">onPressed</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-p">()</span> <span class="devsite-syntax-p">{</span> <span class="devsite-syntax-n">Navigator</span><span class="devsite-syntax-o">.</span><span class="devsite-syntax-n">push</span><span class="devsite-syntax-p">(</span> <span class="devsite-syntax-n">context</span><span class="devsite-syntax-p">,</span> <span class="devsite-syntax-n">MaterialPageRoute<ProfileScreen></span><span class="devsite-syntax-p">(</span> <span class="devsite-syntax-n">builder</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-p">(</span><span class="devsite-syntax-n">context</span><span class="devsite-syntax-p">)</span> <span class="devsite-syntax-o">=</span>> <span class="devsite-syntax-n">ProfileScreen</span><span class="devsite-syntax-p">(</span> <span class="devsite-syntax-n">appBar</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-n">AppBar</span><span class="devsite-syntax-p">(</span> <span class="devsite-syntax-n">title</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-n">const</span> <span class="devsite-syntax-n">Text</span><span class="devsite-syntax-p">(</span><span class="devsite-syntax-s1">'User Profile'</span><span class="devsite-syntax-p">),</span> <span class="devsite-syntax-p">),</span> <span class="devsite-syntax-n">actions</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-p">[</span> <span class="devsite-syntax-n">SignedOutAction</span><span class="devsite-syntax-p">((</span><span class="devsite-syntax-n">context</span><span class="devsite-syntax-p">)</span> <span class="devsite-syntax-p">{</span> <span class="devsite-syntax-n">Navigator</span><span class="devsite-syntax-o">.</span><span class="devsite-syntax-n">of</span><span class="devsite-syntax-p">(</span><span class="devsite-syntax-n">context</span><span class="devsite-syntax-p">)</span><span class="devsite-syntax-o">.</span><span class="devsite-syntax-n">pop</span><span class="devsite-syntax-p">();</span> <span class="devsite-syntax-p">})</span> <span class="devsite-syntax-p">],</span> <span class="devsite-syntax-n">children</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-p">[</span> <span class="devsite-syntax-n">const</span> <span class="devsite-syntax-n">Divider</span><span class="devsite-syntax-p">(),</span> <span class="devsite-syntax-n">Padding</span><span class="devsite-syntax-p">(</span> <span class="devsite-syntax-n">padding</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-n">const</span> <span class="devsite-syntax-n">EdgeInsets</span><span class="devsite-syntax-o">.</span><span class="devsite-syntax-n">all</span><span class="devsite-syntax-p">(</span><span class="devsite-syntax-mi">2</span><span class="devsite-syntax-p">),</span> <span class="devsite-syntax-n">child</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-n">AspectRatio</span><span class="devsite-syntax-p">(</span> <span class="devsite-syntax-n">aspectRatio</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-mi">1</span><span class="devsite-syntax-p">,</span> <span class="devsite-syntax-n">child</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-n">Image</span><span class="devsite-syntax-o">.</span><span class="devsite-syntax-n">asset</span><span class="devsite-syntax-p">(</span><span class="devsite-syntax-s1">'flutterfire_300x.png'</span><span class="devsite-syntax-p">),</span> <span class="devsite-syntax-p">),</span> <span class="devsite-syntax-p">),</span> <span class="devsite-syntax-p">],</span> <span class="devsite-syntax-p">),</span> <span class="devsite-syntax-p">),</span> <span class="devsite-syntax-p">);</span> <span class="devsite-syntax-p">},</span> <span class="devsite-syntax-p">)</span> <span class="devsite-syntax-p">],</span> <span class="devsite-syntax-n">automaticallyImplyLeading</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-n">false</span><span class="devsite-syntax-p">,</span> <span class="devsite-syntax-p">),</span> <span class="devsite-syntax-n">body</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-n">Center</span><span class="devsite-syntax-p">(</span> <span class="devsite-syntax-n">child</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-n">Column</span><span class="devsite-syntax-p">(</span> <span class="devsite-syntax-n">children</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-p">[</span> <span class="devsite-syntax-n">Image</span><span class="devsite-syntax-o">.</span><span class="devsite-syntax-n">asset</span><span class="devsite-syntax-p">(</span><span class="devsite-syntax-s1">'dash.png'</span><span class="devsite-syntax-p">),</span> <span class="devsite-syntax-n">Text</span><span class="devsite-syntax-p">(</span> <span class="devsite-syntax-s1">'Welcome!'</span><span class="devsite-syntax-p">,</span> <span class="devsite-syntax-n">style</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-n">Theme</span><span class="devsite-syntax-o">.</span><span class="devsite-syntax-n">of</span><span class="devsite-syntax-p">(</span><span class="devsite-syntax-n">context</span><span class="devsite-syntax-p">)</span><span class="devsite-syntax-o">.</span><span class="devsite-syntax-n">textTheme</span><span class="devsite-syntax-o">.</span><span class="devsite-syntax-n">displaySmall</span><span class="devsite-syntax-p">,</span> <span class="devsite-syntax-p">),</span> <span class="devsite-syntax-n">const</span> <span class="devsite-syntax-n">SignOutButton</span><span class="devsite-syntax-p">(),</span> <span class="devsite-syntax-p">],</span> <span class="devsite-syntax-p">),</span> <span class="devsite-syntax-p">),</span> <span class="devsite-syntax-p">);</span> <span class="devsite-syntax-p">}</span> <span class="devsite-syntax-p">}</span> </code></pre></devsite-code> <p>Reload your app, and you'll see this on the screen:</p> <p class="image-container"><img alt="ebe5792b765dbf87.png" style="width: 288.00px" src="/static/codelabs/firebase-auth-in-flutter-apps/img/ebe5792b765dbf87.png" srcset="https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/ebe5792b765dbf87_36.png 36w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/ebe5792b765dbf87_48.png 48w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/ebe5792b765dbf87_72.png 72w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/ebe5792b765dbf87_96.png 96w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/ebe5792b765dbf87_480.png 480w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/ebe5792b765dbf87_720.png 720w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/ebe5792b765dbf87_856.png 856w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/ebe5792b765dbf87_960.png 960w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/ebe5792b765dbf87_1440.png 1440w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/ebe5792b765dbf87_1920.png 1920w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/ebe5792b765dbf87_2880.png 2880w" sizes="(max-width: 840px) 100vw, 856px"></p> </google-codelab-step> <google-codelab-step label="Multiplatform Google Auth Sign In" duration="0" step="6"> <h2 class="step-title" id="6" data-text="Multiplatform Google Auth Sign In" tabindex="-1"> 7. Multiplatform Google Auth Sign In </h2> <p>FlutterFire UI also provides widgets and functionality for authenticating with 3rd party providers, such as Google, Twitter, Facebook, Apple, and Github.</p> <p>To integrate with Google authentication, install the official <a href="https://pub.dev/packages/firebase_ui_oauth_google" target="_blank">firebase_ui_oauth_google</a> plugin and it's dependencies, which will handle the native authentication flow. In the terminal, navigate to the root of your flutter project and enter the following command:</p> <div></div><devsite-code><pre translate="no" dir="ltr" is-upgraded>flutter pub add google_sign_in flutter pub add firebase_ui_oauth_google </pre></devsite-code> <h2 is-upgraded id="enable-google-sign-in-provider" data-text="Enable Google Sign-in Provider" tabindex="-1">Enable Google Sign-in Provider</h2> <p>Next, enable the Google provider in the <a href="https://console.firebase.google.com/project/_/authentication/providers" target="_blank">Firebase Console</a>:</p> <ol type="1"> <li>Navigate to the <a href="https://console.firebase.google.com/project/flutterfire-ui-codelab/authentication/providers" target="_blank">Authentication sign-in providers</a> screen in the console.</li> <li>Click "Add new provider". <img alt="8286fb28be94bf30.png" style="width: 624.00px" src="/static/codelabs/firebase-auth-in-flutter-apps/img/8286fb28be94bf30.png" srcset="https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/8286fb28be94bf30_36.png 36w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/8286fb28be94bf30_48.png 48w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/8286fb28be94bf30_72.png 72w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/8286fb28be94bf30_96.png 96w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/8286fb28be94bf30_480.png 480w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/8286fb28be94bf30_720.png 720w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/8286fb28be94bf30_856.png 856w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/8286fb28be94bf30_960.png 960w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/8286fb28be94bf30_1440.png 1440w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/8286fb28be94bf30_1920.png 1920w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/8286fb28be94bf30_2880.png 2880w" sizes="(max-width: 840px) 100vw, 856px"></li> <li>Select "Google". <img alt="c4e28e6f4974be7f.png" style="width: 624.00px" src="/static/codelabs/firebase-auth-in-flutter-apps/img/c4e28e6f4974be7f.png" srcset="https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/c4e28e6f4974be7f_36.png 36w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/c4e28e6f4974be7f_48.png 48w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/c4e28e6f4974be7f_72.png 72w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/c4e28e6f4974be7f_96.png 96w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/c4e28e6f4974be7f_480.png 480w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/c4e28e6f4974be7f_720.png 720w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/c4e28e6f4974be7f_856.png 856w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/c4e28e6f4974be7f_960.png 960w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/c4e28e6f4974be7f_1440.png 1440w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/c4e28e6f4974be7f_1920.png 1920w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/c4e28e6f4974be7f_2880.png 2880w" sizes="(max-width: 840px) 100vw, 856px"></li> <li>Toggle the switch labeled "Enable", and press "Save". <img alt="e74ff86990763826.png" style="width: 624.00px" src="/static/codelabs/firebase-auth-in-flutter-apps/img/e74ff86990763826.png" srcset="https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/e74ff86990763826_36.png 36w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/e74ff86990763826_48.png 48w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/e74ff86990763826_72.png 72w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/e74ff86990763826_96.png 96w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/e74ff86990763826_480.png 480w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/e74ff86990763826_720.png 720w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/e74ff86990763826_856.png 856w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/e74ff86990763826_960.png 960w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/e74ff86990763826_1440.png 1440w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/e74ff86990763826_1920.png 1920w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/e74ff86990763826_2880.png 2880w" sizes="(max-width: 840px) 100vw, 856px"></li> <li>If a modal appears with information about downloading configuration files, click "Done".</li> <li>Confirm that the Google sign-in provider has been added. <img alt="5329ce0543c90d95.png" style="width: 624.00px" src="/static/codelabs/firebase-auth-in-flutter-apps/img/5329ce0543c90d95.png" srcset="https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/5329ce0543c90d95_36.png 36w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/5329ce0543c90d95_48.png 48w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/5329ce0543c90d95_72.png 72w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/5329ce0543c90d95_96.png 96w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/5329ce0543c90d95_480.png 480w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/5329ce0543c90d95_720.png 720w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/5329ce0543c90d95_856.png 856w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/5329ce0543c90d95_960.png 960w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/5329ce0543c90d95_1440.png 1440w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/5329ce0543c90d95_1920.png 1920w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/5329ce0543c90d95_2880.png 2880w" sizes="(max-width: 840px) 100vw, 856px"></li> </ol> <h2 is-upgraded id="add-google-sign-in-button" data-text="Add Google sign-in button" tabindex="-1">Add Google sign-in button</h2> <p>With Google sign-in enabled, add the widget needed to display a stylized Google sign-in button to the sign in page. Navigate to auth_gate.dart file and update the code to the following:</p> <h3 is-upgraded id="auth_gate.dart_6" data-text="auth_gate.dart" tabindex="-1"><a href="https://github.com/flutter/codelabs/firebase-auth-flutterfire-ui/complete/lib/auth_gate.dart" target="_blank">auth_gate.dart</a></h3> <div></div><devsite-code><pre class="devsite-click-to-copy" translate="no" dir="ltr" is-upgraded syntax="Python"><code language="language-dart" class="language-dart" translate="no" dir="ltr"><span class="devsite-syntax-kn">import</span> <span class="devsite-syntax-s1">'package:firebase_auth/firebase_auth.dart'</span> <span class="devsite-syntax-n">hide</span> <span class="devsite-syntax-n">EmailAuthProvider</span><span class="devsite-syntax-p">;</span> <span class="devsite-syntax-kn">import</span> <span class="devsite-syntax-s1">'package:firebase_ui_auth/firebase_ui_auth.dart'</span><span class="devsite-syntax-p">;</span> <span class="devsite-syntax-kn">import</span> <span class="devsite-syntax-s1">'package:firebase_ui_oauth_google/firebase_ui_oauth_google.dart'</span><span class="devsite-syntax-p">;</span> <span class="devsite-syntax-o">//</span> <span class="devsite-syntax-n">new</span> <span class="devsite-syntax-kn">import</span> <span class="devsite-syntax-s1">'package:flutter/material.dart'</span><span class="devsite-syntax-p">;</span> <span class="devsite-syntax-kn">import</span> <span class="devsite-syntax-s1">'home.dart'</span><span class="devsite-syntax-p">;</span> <span class="devsite-syntax-k">class</span> <span class="devsite-syntax-nc">AuthGate</span> <span class="devsite-syntax-n">extends</span> <span class="devsite-syntax-n">StatelessWidget</span> <span class="devsite-syntax-p">{</span> <span class="devsite-syntax-n">const</span> <span class="devsite-syntax-n">AuthGate</span><span class="devsite-syntax-p">({</span><span class="devsite-syntax-nb">super</span><span class="devsite-syntax-o">.</span><span class="devsite-syntax-n">key</span><span class="devsite-syntax-p">});</span> <span class="devsite-syntax-nd">@override</span> <span class="devsite-syntax-n">Widget</span> <span class="devsite-syntax-n">build</span><span class="devsite-syntax-p">(</span><span class="devsite-syntax-n">BuildContext</span> <span class="devsite-syntax-n">context</span><span class="devsite-syntax-p">)</span> <span class="devsite-syntax-p">{</span> <span class="devsite-syntax-k">return</span> <span class="devsite-syntax-n">StreamBuilder<User</span><span class="devsite-syntax-err">?</span>><span class="devsite-syntax-p">(</span> <span class="devsite-syntax-n">stream</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-n">FirebaseAuth</span><span class="devsite-syntax-o">.</span><span class="devsite-syntax-n">instance</span><span class="devsite-syntax-o">.</span><span class="devsite-syntax-n">authStateChanges</span><span class="devsite-syntax-p">(),</span> <span class="devsite-syntax-n">builder</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-p">(</span><span class="devsite-syntax-n">context</span><span class="devsite-syntax-p">,</span> <span class="devsite-syntax-n">snapshot</span><span class="devsite-syntax-p">)</span> <span class="devsite-syntax-p">{</span> <span class="devsite-syntax-k">if</span> <span class="devsite-syntax-p">(</span><span class="devsite-syntax-err">!</span><span class="devsite-syntax-n">snapshot</span><span class="devsite-syntax-o">.</span><span class="devsite-syntax-n">hasData</span><span class="devsite-syntax-p">)</span> <span class="devsite-syntax-p">{</span> <span class="devsite-syntax-k">return</span> <span class="devsite-syntax-n">SignInScreen</span><span class="devsite-syntax-p">(</span> <span class="devsite-syntax-n">providers</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-p">[</span> <span class="devsite-syntax-n">EmailAuthProvider</span><span class="devsite-syntax-p">(),</span> <span class="devsite-syntax-n">GoogleProvider</span><span class="devsite-syntax-p">(</span><span class="devsite-syntax-n">clientId</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-s2">"YOUR_WEBCLIENT_ID"</span><span class="devsite-syntax-p">),</span> <span class="devsite-syntax-o">//</span> <span class="devsite-syntax-n">new</span> <span class="devsite-syntax-p">],</span> <span class="devsite-syntax-n">headerBuilder</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-p">(</span><span class="devsite-syntax-n">context</span><span class="devsite-syntax-p">,</span> <span class="devsite-syntax-n">constraints</span><span class="devsite-syntax-p">,</span> <span class="devsite-syntax-n">shrinkOffset</span><span class="devsite-syntax-p">)</span> <span class="devsite-syntax-p">{</span> <span class="devsite-syntax-k">return</span> <span class="devsite-syntax-n">Padding</span><span class="devsite-syntax-p">(</span> <span class="devsite-syntax-n">padding</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-n">const</span> <span class="devsite-syntax-n">EdgeInsets</span><span class="devsite-syntax-o">.</span><span class="devsite-syntax-n">all</span><span class="devsite-syntax-p">(</span><span class="devsite-syntax-mi">20</span><span class="devsite-syntax-p">),</span> <span class="devsite-syntax-n">child</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-n">AspectRatio</span><span class="devsite-syntax-p">(</span> <span class="devsite-syntax-n">aspectRatio</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-mi">1</span><span class="devsite-syntax-p">,</span> <span class="devsite-syntax-n">child</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-n">Image</span><span class="devsite-syntax-o">.</span><span class="devsite-syntax-n">asset</span><span class="devsite-syntax-p">(</span><span class="devsite-syntax-s1">'flutterfire_300x.png'</span><span class="devsite-syntax-p">),</span> <span class="devsite-syntax-p">),</span> <span class="devsite-syntax-p">);</span> <span class="devsite-syntax-p">},</span> <span class="devsite-syntax-n">subtitleBuilder</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-p">(</span><span class="devsite-syntax-n">context</span><span class="devsite-syntax-p">,</span> <span class="devsite-syntax-n">action</span><span class="devsite-syntax-p">)</span> <span class="devsite-syntax-p">{</span> <span class="devsite-syntax-k">return</span> <span class="devsite-syntax-n">Padding</span><span class="devsite-syntax-p">(</span> <span class="devsite-syntax-n">padding</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-n">const</span> <span class="devsite-syntax-n">EdgeInsets</span><span class="devsite-syntax-o">.</span><span class="devsite-syntax-n">symmetric</span><span class="devsite-syntax-p">(</span><span class="devsite-syntax-n">vertical</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-mf">8.0</span><span class="devsite-syntax-p">),</span> <span class="devsite-syntax-n">child</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-n">action</span> <span class="devsite-syntax-o">==</span> <span class="devsite-syntax-n">AuthAction</span><span class="devsite-syntax-o">.</span><span class="devsite-syntax-n">signIn</span> <span class="devsite-syntax-err">?</span> <span class="devsite-syntax-n">const</span> <span class="devsite-syntax-n">Text</span><span class="devsite-syntax-p">(</span><span class="devsite-syntax-s1">'Welcome to FlutterFire, please sign in!'</span><span class="devsite-syntax-p">)</span> <span class="devsite-syntax-p">:</span> <span class="devsite-syntax-n">const</span> <span class="devsite-syntax-n">Text</span><span class="devsite-syntax-p">(</span><span class="devsite-syntax-s1">'Welcome to Flutterfire, please sign up!'</span><span class="devsite-syntax-p">),</span> <span class="devsite-syntax-p">);</span> <span class="devsite-syntax-p">},</span> <span class="devsite-syntax-n">footerBuilder</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-p">(</span><span class="devsite-syntax-n">context</span><span class="devsite-syntax-p">,</span> <span class="devsite-syntax-n">action</span><span class="devsite-syntax-p">)</span> <span class="devsite-syntax-p">{</span> <span class="devsite-syntax-k">return</span> <span class="devsite-syntax-n">const</span> <span class="devsite-syntax-n">Padding</span><span class="devsite-syntax-p">(</span> <span class="devsite-syntax-n">padding</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-n">EdgeInsets</span><span class="devsite-syntax-o">.</span><span class="devsite-syntax-n">only</span><span class="devsite-syntax-p">(</span><span class="devsite-syntax-n">top</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-mi">16</span><span class="devsite-syntax-p">),</span> <span class="devsite-syntax-n">child</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-n">Text</span><span class="devsite-syntax-p">(</span> <span class="devsite-syntax-s1">'By signing in, you agree to our terms and conditions.'</span><span class="devsite-syntax-p">,</span> <span class="devsite-syntax-n">style</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-n">TextStyle</span><span class="devsite-syntax-p">(</span><span class="devsite-syntax-n">color</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-n">Colors</span><span class="devsite-syntax-o">.</span><span class="devsite-syntax-n">grey</span><span class="devsite-syntax-p">),</span> <span class="devsite-syntax-p">),</span> <span class="devsite-syntax-p">);</span> <span class="devsite-syntax-p">},</span> <span class="devsite-syntax-n">sideBuilder</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-p">(</span><span class="devsite-syntax-n">context</span><span class="devsite-syntax-p">,</span> <span class="devsite-syntax-n">shrinkOffset</span><span class="devsite-syntax-p">)</span> <span class="devsite-syntax-p">{</span> <span class="devsite-syntax-k">return</span> <span class="devsite-syntax-n">Padding</span><span class="devsite-syntax-p">(</span> <span class="devsite-syntax-n">padding</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-n">const</span> <span class="devsite-syntax-n">EdgeInsets</span><span class="devsite-syntax-o">.</span><span class="devsite-syntax-n">all</span><span class="devsite-syntax-p">(</span><span class="devsite-syntax-mi">20</span><span class="devsite-syntax-p">),</span> <span class="devsite-syntax-n">child</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-n">AspectRatio</span><span class="devsite-syntax-p">(</span> <span class="devsite-syntax-n">aspectRatio</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-mi">1</span><span class="devsite-syntax-p">,</span> <span class="devsite-syntax-n">child</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-n">Image</span><span class="devsite-syntax-o">.</span><span class="devsite-syntax-n">asset</span><span class="devsite-syntax-p">(</span><span class="devsite-syntax-s1">'flutterfire_300x.png'</span><span class="devsite-syntax-p">),</span> <span class="devsite-syntax-p">),</span> <span class="devsite-syntax-p">);</span> <span class="devsite-syntax-p">},</span> <span class="devsite-syntax-p">);</span> <span class="devsite-syntax-p">}</span> <span class="devsite-syntax-k">return</span> <span class="devsite-syntax-n">const</span> <span class="devsite-syntax-n">HomeScreen</span><span class="devsite-syntax-p">();</span> <span class="devsite-syntax-p">},</span> <span class="devsite-syntax-p">);</span> <span class="devsite-syntax-p">}</span> <span class="devsite-syntax-p">}</span> </code></pre></devsite-code> <p>The only new code here is the addition of <code translate="no" dir="ltr">GoogleProvider(clientId: "YOUR_WEBCLIENT_ID")</code> to the SignInScreen widget configuration.</p> <p>With that added, reload your app, and you will see a Google sign in button.</p> <p class="image-container"><img alt="aca71a46a011bfb5.png" style="width: 288.00px" src="/static/codelabs/firebase-auth-in-flutter-apps/img/aca71a46a011bfb5.png" srcset="https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/aca71a46a011bfb5_36.png 36w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/aca71a46a011bfb5_48.png 48w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/aca71a46a011bfb5_72.png 72w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/aca71a46a011bfb5_96.png 96w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/aca71a46a011bfb5_480.png 480w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/aca71a46a011bfb5_720.png 720w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/aca71a46a011bfb5_856.png 856w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/aca71a46a011bfb5_960.png 960w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/aca71a46a011bfb5_1440.png 1440w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/aca71a46a011bfb5_1920.png 1920w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/aca71a46a011bfb5_2880.png 2880w" sizes="(max-width: 840px) 100vw, 856px"></p> <h2 is-upgraded id="configure-sign-in-button" data-text="Configure sign-in button" tabindex="-1">Configure sign-in button</h2> <p>The button doesn't work without additional configuration. If you're developing with Flutter Web, this is the only step you have to add for this to work. Other platforms require additional steps, which are discussed in a bit.</p> <ol type="1"> <li>Navigate to the Authentication providers page in the <a href="https://console.firebase.google.com/project/flutterfire-ui-codelab/authentication/providers" target="_blank">Firebase Console</a>.</li> <li>Click on the Google provider. <img alt="9b3a325c5eca6e49.png" style="width: 624.00px" src="/static/codelabs/firebase-auth-in-flutter-apps/img/9b3a325c5eca6e49.png" srcset="https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/9b3a325c5eca6e49_36.png 36w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/9b3a325c5eca6e49_48.png 48w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/9b3a325c5eca6e49_72.png 72w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/9b3a325c5eca6e49_96.png 96w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/9b3a325c5eca6e49_480.png 480w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/9b3a325c5eca6e49_720.png 720w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/9b3a325c5eca6e49_856.png 856w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/9b3a325c5eca6e49_960.png 960w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/9b3a325c5eca6e49_1440.png 1440w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/9b3a325c5eca6e49_1920.png 1920w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/9b3a325c5eca6e49_2880.png 2880w" sizes="(max-width: 840px) 100vw, 856px"></li> <li>Click on the "Web SDK configuration" expansion-panel.</li> <li>Copy the value from ‘Web client ID" <img alt="711a79f0d931c60f.png" style="width: 624.00px" src="/static/codelabs/firebase-auth-in-flutter-apps/img/711a79f0d931c60f.png" srcset="https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/711a79f0d931c60f_36.png 36w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/711a79f0d931c60f_48.png 48w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/711a79f0d931c60f_72.png 72w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/711a79f0d931c60f_96.png 96w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/711a79f0d931c60f_480.png 480w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/711a79f0d931c60f_720.png 720w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/711a79f0d931c60f_856.png 856w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/711a79f0d931c60f_960.png 960w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/711a79f0d931c60f_1440.png 1440w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/711a79f0d931c60f_1920.png 1920w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/711a79f0d931c60f_2880.png 2880w" sizes="(max-width: 840px) 100vw, 856px"></li> <li>Return to your text editor, and update the instance of <code translate="no" dir="ltr">GoogleProvider</code> in the file <code translate="no" dir="ltr">auth_gate.dart</code> by passing this ID to the <code translate="no" dir="ltr">clientId</code> named parameter.</li> </ol> <div></div><devsite-code><pre class="devsite-click-to-copy" translate="no" dir="ltr" is-upgraded syntax="scdoc"><code language="language-dart" class="language-dart" translate="no" dir="ltr">GoogleProvider( clientId: "YOUR_WEBCLIENT_ID" ) </code></pre></devsite-code> <p>Once the web client ID is entered, reload your app. When you press the "Sign in with Google" button, a new window will appear (if you're using web) that walks you through the Google sign in flow. Initially, it looks like this:</p> <p class="image-container"><img alt="14e73e3c9de704bb.png" style="width: 288.00px" src="/static/codelabs/firebase-auth-in-flutter-apps/img/14e73e3c9de704bb.png" srcset="https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/14e73e3c9de704bb_36.png 36w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/14e73e3c9de704bb_48.png 48w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/14e73e3c9de704bb_72.png 72w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/14e73e3c9de704bb_96.png 96w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/14e73e3c9de704bb_480.png 480w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/14e73e3c9de704bb_720.png 720w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/14e73e3c9de704bb_856.png 856w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/14e73e3c9de704bb_960.png 960w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/14e73e3c9de704bb_1440.png 1440w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/14e73e3c9de704bb_1920.png 1920w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/14e73e3c9de704bb_2880.png 2880w" sizes="(max-width: 840px) 100vw, 856px"></p> <h2 is-upgraded id="configure-ios" data-text="Configure iOS" tabindex="-1">Configure iOS</h2> <p>In order for this to work on iOS, there is an additional configuration process.</p> <ol type="1"> <li>Navigate to the Project Settings screen in the <a href="https://console.firebase.google.com/" target="_blank">Firebase console</a>. There will be a card that lists your Firebase apps that looks like this: <img alt="fefa674acbf213cc.png" style="width: 624.00px" src="/static/codelabs/firebase-auth-in-flutter-apps/img/fefa674acbf213cc.png" srcset="https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/fefa674acbf213cc_36.png 36w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/fefa674acbf213cc_48.png 48w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/fefa674acbf213cc_72.png 72w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/fefa674acbf213cc_96.png 96w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/fefa674acbf213cc_480.png 480w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/fefa674acbf213cc_720.png 720w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/fefa674acbf213cc_856.png 856w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/fefa674acbf213cc_960.png 960w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/fefa674acbf213cc_1440.png 1440w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/fefa674acbf213cc_1920.png 1920w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/fefa674acbf213cc_2880.png 2880w" sizes="(max-width: 840px) 100vw, 856px"></li> <li>Click on the iOS. Note that your application name will be different from mine. Where mine says "complete" yours will say "start", if you used the <code translate="no" dir="ltr">flutter-codelabs/firebase-auth-flutterfire-ui/start</code> project to follow along with this codelab.</li> <li>Click the button that says "GoogleServices-Info.plist" to download the configuration file needed. <img alt="f89b3192871dfbe3.png" style="width: 624.00px" src="/static/codelabs/firebase-auth-in-flutter-apps/img/f89b3192871dfbe3.png" srcset="https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/f89b3192871dfbe3_36.png 36w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/f89b3192871dfbe3_48.png 48w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/f89b3192871dfbe3_72.png 72w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/f89b3192871dfbe3_96.png 96w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/f89b3192871dfbe3_480.png 480w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/f89b3192871dfbe3_720.png 720w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/f89b3192871dfbe3_856.png 856w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/f89b3192871dfbe3_960.png 960w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/f89b3192871dfbe3_1440.png 1440w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/f89b3192871dfbe3_1920.png 1920w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/f89b3192871dfbe3_2880.png 2880w" sizes="(max-width: 840px) 100vw, 856px"></li> <li>Drag and drop the downloaded file to the directory called .<code translate="no" dir="ltr">/ios/Runner</code> in your Flutter project.</li> <li>Open Xcode by running the following terminal command from the root of your project: <code translate="no" dir="ltr">open ios/Runner.xcworkspace</code></li> <li>Right-click on the Runner directory and select Add Files to "Runner". <img alt="858986063a4c5201.png" style="width: 384.00px" src="/static/codelabs/firebase-auth-in-flutter-apps/img/858986063a4c5201.png" srcset="https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/858986063a4c5201_36.png 36w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/858986063a4c5201_48.png 48w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/858986063a4c5201_72.png 72w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/858986063a4c5201_96.png 96w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/858986063a4c5201_480.png 480w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/858986063a4c5201_720.png 720w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/858986063a4c5201_856.png 856w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/858986063a4c5201_960.png 960w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/858986063a4c5201_1440.png 1440w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/858986063a4c5201_1920.png 1920w,https://firebase.google.com/static/codelabs/firebase-auth-in-flutter-apps/img/858986063a4c5201_2880.png 2880w" sizes="(max-width: 840px) 100vw, 856px"></li> <li>Select GoogleService-Info.plist from the file manager.</li> <li>Back in your text editor (that isn't Xcode), add the CFBundleURLTypes attributes below into the [my_project]/ios/Runner/Info.plist file.</li> </ol> <div></div><devsite-code><pre class="devsite-click-to-copy" translate="no" dir="ltr" is-upgraded syntax="Transact-SQL"><code language="language-XML" class="language-XML" translate="no" dir="ltr"><<span class="devsite-syntax-err">!</span><span class="devsite-syntax-o">--</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-n">Put</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-n">me</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-ow">in</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-n">the</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-o">[</span><span class="devsite-syntax-n">my_project</span><span class="devsite-syntax-o">]/</span><span class="devsite-syntax-n">ios</span><span class="devsite-syntax-o">/</span><span class="devsite-syntax-n">Runner</span><span class="devsite-syntax-o">/</span><span class="devsite-syntax-n">Info</span><span class="devsite-syntax-p">.</span><span class="devsite-syntax-n">plist</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-k">file</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-o">--</span>> <<span class="devsite-syntax-err">!</span><span class="devsite-syntax-o">--</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-n">Google</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-nf">Sign</span><span class="devsite-syntax-o">-</span><span class="devsite-syntax-ow">in</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-k">Section</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-o">--</span>> <<span class="devsite-syntax-n">key>CFBundleURLTypes</span><<span class="devsite-syntax-o">/</span><span class="devsite-syntax-k">key</span>> <<span class="devsite-syntax-k">array</span>> <span class="devsite-syntax-w"> </span><<span class="devsite-syntax-n">dict</span>> <span class="devsite-syntax-w"> </span><<span class="devsite-syntax-n">key>CFBundleTypeRole</span><<span class="devsite-syntax-o">/</span><span class="devsite-syntax-k">key</span>> <span class="devsite-syntax-w"> </span><<span class="devsite-syntax-n">string>Editor</span><<span class="devsite-syntax-o">/</span><span class="devsite-syntax-n">string</span>> <span class="devsite-syntax-w"> </span><<span class="devsite-syntax-n">key>CFBundleURLSchemes</span><<span class="devsite-syntax-o">/</span><span class="devsite-syntax-k">key</span>> <span class="devsite-syntax-w"> </span><<span class="devsite-syntax-k">array</span>> <span class="devsite-syntax-w"> </span><<span class="devsite-syntax-err">!</span><span class="devsite-syntax-o">--</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-n">TODO</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-nf">Replace</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-n">this</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-k">value</span><span class="devsite-syntax-err">:</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-o">--</span>> <span class="devsite-syntax-w"> </span><<span class="devsite-syntax-err">!</span><span class="devsite-syntax-o">--</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-n">Copied</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-k">from</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-n">GoogleService</span><span class="devsite-syntax-o">-</span><span class="devsite-syntax-n">Info</span><span class="devsite-syntax-p">.</span><span class="devsite-syntax-n">plist</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-k">key</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-n">REVERSED_CLIENT_ID</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-o">--</span>> <span class="devsite-syntax-w"> </span><<span class="devsite-syntax-n">string>com</span><span class="devsite-syntax-p">.</span><span class="devsite-syntax-n">googleusercontent</span><span class="devsite-syntax-p">.</span><span class="devsite-syntax-n">apps</span><span class="devsite-syntax-mf">.861823949799</span><span class="devsite-syntax-o">-</span><span class="devsite-syntax-n">vc35cprkp249096uujjn0vvnmcvjppkn</span><<span class="devsite-syntax-o">/</span><span class="devsite-syntax-n">string</span>> <span class="devsite-syntax-w"> </span><<span class="devsite-syntax-o">/</span><span class="devsite-syntax-k">array</span>> <span class="devsite-syntax-w"> </span><<span class="devsite-syntax-o">/</span><span class="devsite-syntax-n">dict</span>> <<span class="devsite-syntax-o">/</span><span class="devsite-syntax-k">array</span>> <<span class="devsite-syntax-err">!</span><span class="devsite-syntax-c1">-- End of the Google Sign-in Section --</span>> </code></pre></devsite-code> <ol type="1" start="9"> <li>You need to replace the <code translate="no" dir="ltr">GoogleProvider.clientId</code> that you added in the web setup with the Client Id associated with your Firebase iOS client id. First, You can find this ID in the <code translate="no" dir="ltr">firebase_options.dart</code> file, as part of the <code translate="no" dir="ltr">iOS</code> constant. Copy the value passed to <code translate="no" dir="ltr">iOSClientId</code>.</li> </ol> <div></div><devsite-code><pre class="devsite-click-to-copy" translate="no" dir="ltr" is-upgraded syntax="GDScript"><code language="language-dart" class="language-dart" translate="no" dir="ltr"><span class="devsite-syntax-k">static</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-k">const</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-n">FirebaseOptions</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-n">ios</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-o">=</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-n">FirebaseOptions</span><span class="devsite-syntax-p">(</span> <span class="devsite-syntax-w"> </span><span class="devsite-syntax-n">apiKey</span><span class="devsite-syntax-p">:</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-s1">'YOUR API KEY'</span><span class="devsite-syntax-p">,</span> <span class="devsite-syntax-w"> </span><span class="devsite-syntax-n">appId</span><span class="devsite-syntax-p">:</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-s1">'YOUR APP ID'</span><span class="devsite-syntax-p">,</span> <span class="devsite-syntax-w"> </span><span class="devsite-syntax-n">messagingSenderId</span><span class="devsite-syntax-p">:</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-s1">''</span><span class="devsite-syntax-p">,</span> <span class="devsite-syntax-w"> </span><span class="devsite-syntax-n">projectId</span><span class="devsite-syntax-p">:</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-s1">'PROJECT_ID'</span><span class="devsite-syntax-p">,</span> <span class="devsite-syntax-w"> </span><span class="devsite-syntax-n">storageBucket</span><span class="devsite-syntax-p">:</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-s1">'PROJECT_ID.firebasestorage.app'</span><span class="devsite-syntax-p">,</span> <span class="devsite-syntax-w"> </span><span class="devsite-syntax-n">iosClientId</span><span class="devsite-syntax-p">:</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-s1">'IOS CLIENT ID'</span><span class="devsite-syntax-p">,</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-o">//</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-n">Find</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-n">your</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-n">iOS</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-n">client</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-n">Id</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-n">here</span><span class="devsite-syntax-o">.</span> <span class="devsite-syntax-w"> </span><span class="devsite-syntax-n">iosBundleId</span><span class="devsite-syntax-p">:</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-s1">'com.example.BUNDLE'</span><span class="devsite-syntax-p">,</span> <span class="devsite-syntax-p">);</span> </code></pre></devsite-code> <ol type="1" start="10"> <li>Paste that value into the <code translate="no" dir="ltr">GoogleProvider.clientId</code> argument in the <code translate="no" dir="ltr">AuthGate</code> widget.</li> </ol> <div></div><devsite-code><pre class="devsite-click-to-copy" translate="no" dir="ltr" is-upgraded syntax="Python"><code language="language-dart" class="language-dart" translate="no" dir="ltr"><span class="devsite-syntax-kn">import</span> <span class="devsite-syntax-s1">'package:firebase_auth/firebase_auth.dart'</span> <span class="devsite-syntax-n">hide</span> <span class="devsite-syntax-n">EmailAuthProvider</span><span class="devsite-syntax-p">;</span> <span class="devsite-syntax-kn">import</span> <span class="devsite-syntax-s1">'package:firebase_ui_auth/firebase_ui_auth.dart'</span><span class="devsite-syntax-p">;</span> <span class="devsite-syntax-kn">import</span> <span class="devsite-syntax-s1">'package:firebase_ui_oauth_google/firebase_ui_oauth_google.dart'</span><span class="devsite-syntax-p">;</span> <span class="devsite-syntax-kn">import</span> <span class="devsite-syntax-s1">'package:flutter/material.dart'</span><span class="devsite-syntax-p">;</span> <span class="devsite-syntax-kn">import</span> <span class="devsite-syntax-s1">'home.dart'</span><span class="devsite-syntax-p">;</span> <span class="devsite-syntax-k">class</span> <span class="devsite-syntax-nc">AuthGate</span> <span class="devsite-syntax-n">extends</span> <span class="devsite-syntax-n">StatelessWidget</span> <span class="devsite-syntax-p">{</span> <span class="devsite-syntax-n">const</span> <span class="devsite-syntax-n">AuthGate</span><span class="devsite-syntax-p">({</span><span class="devsite-syntax-nb">super</span><span class="devsite-syntax-o">.</span><span class="devsite-syntax-n">key</span><span class="devsite-syntax-p">});</span> <span class="devsite-syntax-nd">@override</span> <span class="devsite-syntax-n">Widget</span> <span class="devsite-syntax-n">build</span><span class="devsite-syntax-p">(</span><span class="devsite-syntax-n">BuildContext</span> <span class="devsite-syntax-n">context</span><span class="devsite-syntax-p">)</span> <span class="devsite-syntax-p">{</span> <span class="devsite-syntax-k">return</span> <span class="devsite-syntax-n">StreamBuilder<User</span><span class="devsite-syntax-err">?</span>><span class="devsite-syntax-p">(</span> <span class="devsite-syntax-n">stream</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-n">FirebaseAuth</span><span class="devsite-syntax-o">.</span><span class="devsite-syntax-n">instance</span><span class="devsite-syntax-o">.</span><span class="devsite-syntax-n">authStateChanges</span><span class="devsite-syntax-p">(),</span> <span class="devsite-syntax-n">builder</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-p">(</span><span class="devsite-syntax-n">context</span><span class="devsite-syntax-p">,</span> <span class="devsite-syntax-n">snapshot</span><span class="devsite-syntax-p">)</span> <span class="devsite-syntax-p">{</span> <span class="devsite-syntax-k">if</span> <span class="devsite-syntax-p">(</span><span class="devsite-syntax-err">!</span><span class="devsite-syntax-n">snapshot</span><span class="devsite-syntax-o">.</span><span class="devsite-syntax-n">hasData</span><span class="devsite-syntax-p">)</span> <span class="devsite-syntax-p">{</span> <span class="devsite-syntax-k">return</span> <span class="devsite-syntax-n">SignInScreen</span><span class="devsite-syntax-p">(</span> <span class="devsite-syntax-n">providers</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-p">[</span> <span class="devsite-syntax-n">EmailAuthProvider</span><span class="devsite-syntax-p">(),</span> <span class="devsite-syntax-n">GoogleProvider</span><span class="devsite-syntax-p">(</span><span class="devsite-syntax-n">clientId</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-s2">"YOUR IOS CLIENT ID"</span><span class="devsite-syntax-p">),</span> <span class="devsite-syntax-o">//</span> <span class="devsite-syntax-n">replace</span> <span class="devsite-syntax-n">String</span> <span class="devsite-syntax-p">],</span> <span class="devsite-syntax-n">headerBuilder</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-p">(</span><span class="devsite-syntax-n">context</span><span class="devsite-syntax-p">,</span> <span class="devsite-syntax-n">constraints</span><span class="devsite-syntax-p">,</span> <span class="devsite-syntax-n">shrinkOffset</span><span class="devsite-syntax-p">)</span> <span class="devsite-syntax-p">{</span> <span class="devsite-syntax-k">return</span> <span class="devsite-syntax-n">Padding</span><span class="devsite-syntax-p">(</span> <span class="devsite-syntax-n">padding</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-n">const</span> <span class="devsite-syntax-n">EdgeInsets</span><span class="devsite-syntax-o">.</span><span class="devsite-syntax-n">all</span><span class="devsite-syntax-p">(</span><span class="devsite-syntax-mi">20</span><span class="devsite-syntax-p">),</span> <span class="devsite-syntax-n">child</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-n">AspectRatio</span><span class="devsite-syntax-p">(</span> <span class="devsite-syntax-n">aspectRatio</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-mi">1</span><span class="devsite-syntax-p">,</span> <span class="devsite-syntax-n">child</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-n">Image</span><span class="devsite-syntax-o">.</span><span class="devsite-syntax-n">asset</span><span class="devsite-syntax-p">(</span><span class="devsite-syntax-s1">'flutterfire_300x.png'</span><span class="devsite-syntax-p">),</span> <span class="devsite-syntax-p">),</span> <span class="devsite-syntax-p">);</span> <span class="devsite-syntax-p">},</span> <span class="devsite-syntax-n">subtitleBuilder</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-p">(</span><span class="devsite-syntax-n">context</span><span class="devsite-syntax-p">,</span> <span class="devsite-syntax-n">action</span><span class="devsite-syntax-p">)</span> <span class="devsite-syntax-p">{</span> <span class="devsite-syntax-k">return</span> <span class="devsite-syntax-n">Padding</span><span class="devsite-syntax-p">(</span> <span class="devsite-syntax-n">padding</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-n">const</span> <span class="devsite-syntax-n">EdgeInsets</span><span class="devsite-syntax-o">.</span><span class="devsite-syntax-n">symmetric</span><span class="devsite-syntax-p">(</span><span class="devsite-syntax-n">vertical</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-mf">8.0</span><span class="devsite-syntax-p">),</span> <span class="devsite-syntax-n">child</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-n">action</span> <span class="devsite-syntax-o">==</span> <span class="devsite-syntax-n">AuthAction</span><span class="devsite-syntax-o">.</span><span class="devsite-syntax-n">signIn</span> <span class="devsite-syntax-err">?</span> <span class="devsite-syntax-n">const</span> <span class="devsite-syntax-n">Text</span><span class="devsite-syntax-p">(</span><span class="devsite-syntax-s1">'Welcome to FlutterFire, please sign in!'</span><span class="devsite-syntax-p">)</span> <span class="devsite-syntax-p">:</span> <span class="devsite-syntax-n">const</span> <span class="devsite-syntax-n">Text</span><span class="devsite-syntax-p">(</span><span class="devsite-syntax-s1">'Welcome to Flutterfire, please sign up!'</span><span class="devsite-syntax-p">),</span> <span class="devsite-syntax-p">);</span> <span class="devsite-syntax-p">},</span> <span class="devsite-syntax-n">footerBuilder</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-p">(</span><span class="devsite-syntax-n">context</span><span class="devsite-syntax-p">,</span> <span class="devsite-syntax-n">action</span><span class="devsite-syntax-p">)</span> <span class="devsite-syntax-p">{</span> <span class="devsite-syntax-k">return</span> <span class="devsite-syntax-n">const</span> <span class="devsite-syntax-n">Padding</span><span class="devsite-syntax-p">(</span> <span class="devsite-syntax-n">padding</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-n">EdgeInsets</span><span class="devsite-syntax-o">.</span><span class="devsite-syntax-n">only</span><span class="devsite-syntax-p">(</span><span class="devsite-syntax-n">top</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-mi">16</span><span class="devsite-syntax-p">),</span> <span class="devsite-syntax-n">child</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-n">Text</span><span class="devsite-syntax-p">(</span> <span class="devsite-syntax-s1">'By signing in, you agree to our terms and conditions.'</span><span class="devsite-syntax-p">,</span> <span class="devsite-syntax-n">style</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-n">TextStyle</span><span class="devsite-syntax-p">(</span><span class="devsite-syntax-n">color</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-n">Colors</span><span class="devsite-syntax-o">.</span><span class="devsite-syntax-n">grey</span><span class="devsite-syntax-p">),</span> <span class="devsite-syntax-p">),</span> <span class="devsite-syntax-p">);</span> <span class="devsite-syntax-p">},</span> <span class="devsite-syntax-n">sideBuilder</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-p">(</span><span class="devsite-syntax-n">context</span><span class="devsite-syntax-p">,</span> <span class="devsite-syntax-n">shrinkOffset</span><span class="devsite-syntax-p">)</span> <span class="devsite-syntax-p">{</span> <span class="devsite-syntax-k">return</span> <span class="devsite-syntax-n">Padding</span><span class="devsite-syntax-p">(</span> <span class="devsite-syntax-n">padding</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-n">const</span> <span class="devsite-syntax-n">EdgeInsets</span><span class="devsite-syntax-o">.</span><span class="devsite-syntax-n">all</span><span class="devsite-syntax-p">(</span><span class="devsite-syntax-mi">20</span><span class="devsite-syntax-p">),</span> <span class="devsite-syntax-n">child</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-n">AspectRatio</span><span class="devsite-syntax-p">(</span> <span class="devsite-syntax-n">aspectRatio</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-mi">1</span><span class="devsite-syntax-p">,</span> <span class="devsite-syntax-n">child</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-n">Image</span><span class="devsite-syntax-o">.</span><span class="devsite-syntax-n">asset</span><span class="devsite-syntax-p">(</span><span class="devsite-syntax-s1">'flutterfire_300x.png'</span><span class="devsite-syntax-p">),</span> <span class="devsite-syntax-p">),</span> <span class="devsite-syntax-p">);</span> <span class="devsite-syntax-p">},</span> <span class="devsite-syntax-p">);</span> <span class="devsite-syntax-p">}</span> <span class="devsite-syntax-k">return</span> <span class="devsite-syntax-n">const</span> <span class="devsite-syntax-n">HomeScreen</span><span class="devsite-syntax-p">();</span> <span class="devsite-syntax-p">},</span> <span class="devsite-syntax-p">);</span> <span class="devsite-syntax-p">}</span> <span class="devsite-syntax-p">}</span> </code></pre></devsite-code> <p>If your Flutter app is running in iOS already, you have to shut it down completely and then re-run the application. Otherwise, run the app in iOS.</p> </google-codelab-step> <google-codelab-step label="Congratulations!" duration="0" step="7"> <h2 class="step-title" id="7" data-text="Congratulations!" tabindex="-1"> 8. Congratulations! </h2> <p>You have completed the Firebase Auth UI for Flutter codelab . You can find the completed code for this Codelab in the "complete" directory on github: <a href="https://github.com/flutter/codelabs" target="_blank">Flutter Codelabs</a></p> <h2 class="checklist" is-upgraded id="what-weve-covered" data-text="What we've covered" tabindex="-1">What we've covered</h2> <ul class="checklist"> <li>Setting up a Flutter app to use Firebase</li> <li>Setting up a Firebase project in the Firebase console</li> <li>FlutterFire CLI</li> <li>Firebase CLI</li> <li>Using Firebase Authentication</li> <li>Using FlutterFire UI to handle Firebase auth in your Flutter app easily</li> </ul> <h2 is-upgraded id="next-steps" data-text="Next Steps" tabindex="-1">Next Steps</h2> <ul> <li>Learn more about using Firestore and Authentication in Flutter: <a href="https://firebase.google.com/codelabs/firebase-get-to-know-flutter" target="_blank">Get to know Firebase for Flutter Codelab</a></li> <li>Explore other Firebase tools for building your Flutter application:</li> <li><a href="https://firebase.google.com/docs/storage" target="_blank">Cloud Storage</a></li> <li><a href="https://firebase.google.com/docs/functions" target="_blank">Cloud Functions</a></li> <li><a href="https://firebase.google.com/docs/database" target="_blank">Realtime Database</a></li> </ul> <h2 is-upgraded id="learn-more" data-text="Learn more" tabindex="-1">Learn more</h2> <ul> <li>Firebase site: <a href="https://firebase.google.com/" target="_blank">firebase.google.com</a></li> <li>Flutter site: <a href="https://flutter.dev/" target="_blank">flutter.dev</a></li> <li>FlutterFire Firebase Flutter widgets: <a href="https://firebase.flutter.dev/" target="_blank">firebase.flutter.dev</a></li> <li><a href="https://www.youtube.com/user/Firebase/featured" target="_blank">Firebase YouTube channel</a></li> <li><a href="https://www.youtube.com/FlutterDev" target="_blank">Flutter YouTube channel</a></li> </ul> <p>Sparky is here to celebrate with you!</p> <p class="image-container"><img alt="2a0ad195769368b1.gif" style="width: 472.29px" src="/static/codelabs/firebase-auth-in-flutter-apps/img/2a0ad195769368b1.gif"></p> </google-codelab-step> </google-codelab> </div> <div class="devsite-floating-action-buttons"> </div> </article> <devsite-content-footer class="nocontent"> <p>Except as otherwise noted, the content of this page is licensed under the <a href="https://creativecommons.org/licenses/by/4.0/">Creative Commons Attribution 4.0 License</a>, and code samples are licensed under the <a href="https://www.apache.org/licenses/LICENSE-2.0">Apache 2.0 License</a>. For details, see the <a href="https://developers.google.com/site-policies">Google Developers Site Policies</a>. Java is a registered trademark of Oracle and/or its affiliates.</p> </devsite-content-footer> <devsite-notification > </devsite-notification> <div class="devsite-content-data"> <template class="devsite-content-data-template"> [[["Easy to understand","easyToUnderstand","thumb-up"],["Solved my problem","solvedMyProblem","thumb-up"],["Other","otherUp","thumb-up"]],[["Missing the information I need","missingTheInformationINeed","thumb-down"],["Too complicated / too many steps","tooComplicatedTooManySteps","thumb-down"],["Out of date","outOfDate","thumb-down"],["Samples / code issue","samplesCodeIssue","thumb-down"],["Other","otherDown","thumb-down"]],[],[],[]] </template> </div> </devsite-content> </main> <devsite-footer-promos class="devsite-footer"> </devsite-footer-promos> <devsite-footer-linkboxes class="devsite-footer"> <nav class="devsite-footer-linkboxes nocontent" aria-label="Footer links"> <ul class="devsite-footer-linkboxes-list"> <li class="devsite-footer-linkbox "> <h3 class="devsite-footer-linkbox-heading no-link">Learn</h3> <ul class="devsite-footer-linkbox-list"> <li class="devsite-footer-linkbox-item"> <a href="/docs/" class="devsite-footer-linkbox-link gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Footer Link (index 1)" > Developer guides </a> </li> <li class="devsite-footer-linkbox-item"> <a href="/docs/reference/" class="devsite-footer-linkbox-link gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Footer Link (index 2)" > SDK & API reference </a> </li> <li class="devsite-footer-linkbox-item"> <a href="/docs/samples/" class="devsite-footer-linkbox-link gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Footer Link (index 3)" > Samples </a> </li> <li class="devsite-footer-linkbox-item"> <a href="/docs/libraries/" class="devsite-footer-linkbox-link gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Footer Link (index 4)" > Libraries </a> </li> <li class="devsite-footer-linkbox-item"> <a href="//github.com/firebase/" class="devsite-footer-linkbox-link gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Footer Link (index 5)" > GitHub </a> </li> </ul> </li> <li class="devsite-footer-linkbox "> <h3 class="devsite-footer-linkbox-heading no-link">Stay connected</h3> <ul class="devsite-footer-linkbox-list"> <li class="devsite-footer-linkbox-item"> <a href="//firebase.blog" class="devsite-footer-linkbox-link gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Footer Link (index 1)" > Check out the blog </a> </li> <li class="devsite-footer-linkbox-item"> <a href="//www.reddit.com/r/Firebase" class="devsite-footer-linkbox-link gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Footer Link (index 2)" > Find us on Reddit </a> </li> <li class="devsite-footer-linkbox-item"> <a href="//x.com/Firebase" class="devsite-footer-linkbox-link gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Footer Link (index 3)" > Follow on X </a> </li> <li class="devsite-footer-linkbox-item"> <a href="//www.youtube.com/user/Firebase" class="devsite-footer-linkbox-link gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Footer Link (index 4)" > Subscribe on YouTube </a> </li> <li class="devsite-footer-linkbox-item"> <a href="/community/events" class="devsite-footer-linkbox-link gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Footer Link (index 5)" > Attend an event </a> </li> </ul> </li> <li class="devsite-footer-linkbox "> <h3 class="devsite-footer-linkbox-heading no-link">Support</h3> <ul class="devsite-footer-linkbox-list"> <li class="devsite-footer-linkbox-item"> <a href="/support/" class="devsite-footer-linkbox-link gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Footer Link (index 1)" > Contact support </a> </li> <li class="devsite-footer-linkbox-item"> <a href="//stackoverflow.com/questions/tagged/firebase" class="devsite-footer-linkbox-link gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Footer Link (index 2)" > Stack Overflow </a> </li> <li class="devsite-footer-linkbox-item"> <a href="//firebase.community/" class="devsite-footer-linkbox-link gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Footer Link (index 3)" > Slack community </a> </li> <li class="devsite-footer-linkbox-item"> <a href="//groups.google.com/forum/#!forum/firebase-talk" class="devsite-footer-linkbox-link gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Footer Link (index 4)" > Google group </a> </li> <li class="devsite-footer-linkbox-item"> <a href="/support/releases" class="devsite-footer-linkbox-link gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Footer Link (index 5)" > Release notes </a> </li> <li class="devsite-footer-linkbox-item"> <a href="/brand-guidelines/" class="devsite-footer-linkbox-link gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Footer Link (index 6)" > Brand guidelines </a> </li> <li class="devsite-footer-linkbox-item"> <a href="/support/faq/" class="devsite-footer-linkbox-link gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Footer Link (index 7)" > FAQs </a> </li> </ul> </li> </ul> </nav> </devsite-footer-linkboxes> <devsite-footer-utility class="devsite-footer"> <div class="devsite-footer-utility nocontent"> <nav class="devsite-footer-sites" aria-label="Other Google Developers websites"> <a href="https://developers.google.com/" class="devsite-footer-sites-logo-link gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Footer Google Developers Link"> <picture> <source srcset="https://www.gstatic.com/devrel-devsite/prod/v870e399c64f7c43c99a3043db4b3a74327bb93d0914e84a0c3dba90bbfd67625/firebase/images/lockup-google-for-developers-dark-theme.svg" media="(prefers-color-scheme: none)" class="devsite-dark-theme" loading="lazy" alt="Google Developers"> <img class="devsite-footer-sites-logo" src="https://www.gstatic.com/devrel-devsite/prod/v870e399c64f7c43c99a3043db4b3a74327bb93d0914e84a0c3dba90bbfd67625/firebase/images/lockup-google-for-developers.svg" loading="lazy" alt="Google Developers"> </picture> </a> <ul class="devsite-footer-sites-list"> <li class="devsite-footer-sites-item"> <a href="//developer.android.com" class="devsite-footer-sites-link gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Footer Android Link" > Android </a> </li> <li class="devsite-footer-sites-item"> <a href="//developer.chrome.com/home" class="devsite-footer-sites-link gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Footer Chrome Link" > Chrome </a> </li> <li class="devsite-footer-sites-item"> <a href="//firebase.google.com" class="devsite-footer-sites-link gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Footer Firebase Link" > Firebase </a> </li> <li class="devsite-footer-sites-item"> <a href="//cloud.google.com" class="devsite-footer-sites-link gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Footer Google Cloud Platform Link" > Google Cloud Platform </a> </li> <li class="devsite-footer-sites-item"> <a href="//developers.google.com/products/" class="devsite-footer-sites-link gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Footer All products Link" > All products </a> </li> </ul> </nav> <nav class="devsite-footer-utility-links" aria-label="Utility links"> <ul class="devsite-footer-utility-list"> <li class="devsite-footer-utility-item "> <a class="devsite-footer-utility-link gc-analytics-event" href="/terms/" data-category="Site-Wide Custom Events" data-label="Footer Terms link" > Terms </a> </li> <li class="devsite-footer-utility-item "> <a class="devsite-footer-utility-link gc-analytics-event" href="//policies.google.com/privacy" data-category="Site-Wide Custom Events" data-label="Footer Privacy link" > Privacy </a> </li> <li class="devsite-footer-utility-item glue-cookie-notification-bar-control"> <a class="devsite-footer-utility-link gc-analytics-event" href="#" data-category="Site-Wide Custom Events" data-label="Footer Manage cookies link" aria-hidden="true" > Manage cookies </a> </li> </ul> <devsite-language-selector> <ul role="presentation"> <li role="presentation"> <a role="menuitem" lang="en" >English</a> </li> <li role="presentation"> <a role="menuitem" lang="de" >Deutsch</a> </li> <li role="presentation"> <a role="menuitem" lang="es" >Español</a> </li> <li role="presentation"> <a role="menuitem" lang="es_419" >Español – América Latina</a> </li> <li role="presentation"> <a role="menuitem" lang="fr" >Français</a> </li> <li role="presentation"> <a role="menuitem" lang="id" >Indonesia</a> </li> <li role="presentation"> <a role="menuitem" lang="it" >Italiano</a> </li> <li role="presentation"> <a role="menuitem" lang="pl" >Polski</a> </li> <li role="presentation"> <a role="menuitem" lang="pt" >Português</a> </li> <li role="presentation"> <a role="menuitem" lang="pt_br" >Português – Brasil</a> </li> <li role="presentation"> <a role="menuitem" lang="vi" >Tiếng Việt</a> </li> <li role="presentation"> <a role="menuitem" lang="tr" >Türkçe</a> </li> <li role="presentation"> <a role="menuitem" lang="ru" >Русский</a> </li> <li role="presentation"> <a role="menuitem" lang="he" >עברית</a> </li> <li role="presentation"> <a role="menuitem" lang="ar" >العربيّة</a> </li> <li role="presentation"> <a role="menuitem" lang="fa" >فارسی</a> </li> <li role="presentation"> <a role="menuitem" lang="hi" >हिंदी</a> </li> <li role="presentation"> <a role="menuitem" lang="bn" >বাংলা</a> </li> <li role="presentation"> <a role="menuitem" lang="th" >ภาษาไทย</a> </li> <li role="presentation"> <a role="menuitem" lang="zh_cn" >中文 – 简体</a> </li> <li role="presentation"> <a role="menuitem" lang="zh_tw" >中文 – 繁體</a> </li> <li role="presentation"> <a role="menuitem" lang="ja" >日本語</a> </li> <li role="presentation"> <a role="menuitem" lang="ko" >한국어</a> </li> </ul> </devsite-language-selector> </nav> </div> </devsite-footer-utility> <devsite-panel></devsite-panel> <devsite-concierge data-info-panel data-ai-panel > </devsite-concierge> </section></section> <devsite-sitemask></devsite-sitemask> <devsite-snackbar></devsite-snackbar> <devsite-tooltip ></devsite-tooltip> <devsite-heading-link></devsite-heading-link> <devsite-analytics> <script type="application/json" analytics>[]</script> <script type="application/json" tag-management>{"at": "True", "ga4": [], "ga4p": [], "gtm": [{"id": "GTM-N84485", "purpose": 0}], "parameters": {"internalUser": "False", "language": {"machineTranslated": "False", "requested": "en", "served": "en"}, "pageType": "codelab", "projectName": null, "signedIn": "False", "tenant": "firebase", "recommendations": {"sourcePage": "", "sourceType": 0, "sourceRank": 0, "sourceIdenticalDescriptions": 0, "sourceTitleWords": 0, "sourceDescriptionWords": 0, "experiment": ""}, "experiment": {"ids": ""}}}</script> </devsite-analytics> <devsite-badger></devsite-badger> <firebase-gtm></firebase-gtm> <firebase-utm></firebase-utm> <script nonce="UhguBzfMVf4N1k2VuaLiJoz58g+xiF"> (function(d,e,v,s,i,t,E){d['GoogleDevelopersObject']=i; t=e.createElement(v);t.async=1;t.src=s;E=e.getElementsByTagName(v)[0]; E.parentNode.insertBefore(t,E);})(window, document, 'script', 'https://www.gstatic.com/devrel-devsite/prod/v870e399c64f7c43c99a3043db4b3a74327bb93d0914e84a0c3dba90bbfd67625/firebase/js/app_loader.js', '[4,"en",null,"/js/devsite_app_module.js","https://www.gstatic.com/devrel-devsite/prod/v870e399c64f7c43c99a3043db4b3a74327bb93d0914e84a0c3dba90bbfd67625","https://www.gstatic.com/devrel-devsite/prod/v870e399c64f7c43c99a3043db4b3a74327bb93d0914e84a0c3dba90bbfd67625/firebase","https://firebase-dot-devsite-v2-prod.appspot.com",1,null,["/_pwa/firebase/manifest.json","https://www.gstatic.com/devrel-devsite/prod/v870e399c64f7c43c99a3043db4b3a74327bb93d0914e84a0c3dba90bbfd67625/images/video-placeholder.svg","https://www.gstatic.com/devrel-devsite/prod/v870e399c64f7c43c99a3043db4b3a74327bb93d0914e84a0c3dba90bbfd67625/firebase/images/favicon.png","https://www.gstatic.com/devrel-devsite/prod/v870e399c64f7c43c99a3043db4b3a74327bb93d0914e84a0c3dba90bbfd67625/firebase/images/lockup.svg","https://fonts.googleapis.com/css?family=Google+Sans:400,500|Roboto:400,400italic,500,500italic,700,700italic|Roboto+Mono:400,500,700&display=swap"],1,null,[1,6,8,12,14,17,21,25,50,52,63,70,75,76,80,87,91,92,93,97,98,100,101,102,103,104,105,107,108,109,110,112,113,117,118,120,122,124,125,126,127,129,130,131,132,133,134,135,136,138,140,141,147,148,149,151,152,156,157,158,159,161,163,164,168,169,170,179,180,182,183,186,191,193,196],"AIzaSyAP-jjEJBzmIyKR4F-3XITp8yM9T1gEEI8","AIzaSyB6xiKGDR5O3Ak2okS4rLkauxGUG7XP0hg","firebase.google.com","AIzaSyAQk0fBONSGUqCNznf6Krs82Ap1-NV6J4o","AIzaSyCCxcqdrZ_7QMeLCRY20bh_SXdAYqy70KY",null,null,null,["MiscFeatureFlags__developers_footer_dark_image","Cloud__enable_llm_concierge_chat","Experiments__reqs_query_experiments","Cloud__enable_cloud_facet_chat","MiscFeatureFlags__developers_footer_image","MiscFeatureFlags__enable_variable_operator","Profiles__enable_complete_playlist_endpoint","Cloud__enable_cloud_dlp_service","CloudShell__cloud_code_overflow_menu","Profiles__enable_recognition_badges","MiscFeatureFlags__enable_dark_theme","Search__enable_ai_eligibility_checks","Profiles__enable_public_developer_profiles","Cloud__enable_cloudx_ping","MiscFeatureFlags__enable_explain_this_code","Profiles__enable_release_notes_notifications","DevPro__enable_cloud_innovators_plus","Significatio__enable_by_tenant","MiscFeatureFlags__enable_project_variables","Profiles__require_profile_eligibility_for_signin","Concierge__enable_pushui","Cloud__enable_cloudx_experiment_ids","MiscFeatureFlags__enable_firebase_utm","Concierge__enable_concierge","Cloud__enable_free_trial_server_call","Cloud__enable_cloud_shell_fte_user_flow","Search__enable_dynamic_content_confidential_banner","Profiles__enable_developer_profiles_callout","Profiles__enable_profile_collections","TpcFeatures__enable_mirror_tenant_redirects","Cloud__enable_cloud_shell","DevPro__enable_developer_subscriptions","Profiles__enable_page_saving","Search__enable_page_map","EngEduTelemetry__enable_engedu_telemetry","MiscFeatureFlags__enable_view_transitions","CloudShell__cloud_shell_button","Profiles__enable_completecodelab_endpoint","Profiles__enable_awarding_url","Cloud__enable_legacy_calculator_redirect","Search__enable_suggestions_from_borg","MiscFeatureFlags__emergency_css","TpcFeatures__enable_required_headers","Profiles__enable_dashboard_curated_recommendations","Analytics__enable_clearcut_logging","BookNav__enable_tenant_cache_key","Search__enable_ai_search_summaries"],null,null,"AIzaSyBLEMok-5suZ67qRPzx0qUtbnLmyT_kCVE","https://developerscontentserving-pa.clients6.google.com","AIzaSyCM4QpTRSqP5qI4Dvjt4OAScIN8sOUlO-k","https://developerscontentsearch-pa.clients6.google.com",1,4,null,"https://developerprofiles-pa.clients6.google.com",[4,"firebase","Firebase","firebase.google.com",null,"firebase-dot-devsite-v2-prod.appspot.com",null,null,[1,1,null,null,null,null,null,null,null,null,null,[1],null,null,null,null,null,null,[1],[1,null,null,[1]],null,null,null,[1,null,1],[1,1,null,null,1]],null,[68,null,null,null,null,null,"/images/lockup.svg","/images/touchicon-180.png",null,null,null,1,1,1,null,null,null,null,null,null,null,2,null,null,null,"/images/lockup.svg",[]],[],null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,[6,1,20,22,23,29,37],null,[[],[1,1]],[[null,null,null,null,["UA-24532603-9"],["GTM-N84485"],null,null,null,null,[["UA-24532603-9",1]],[["GTM-N84485",1]],1],[[36,4],[17,1],[46,8],[2,5],[16,2]],null,1],null,4],null,"pk_live_5170syrHvgGVmSx9sBrnWtA5luvk9BwnVcvIi7HizpwauFG96WedXsuXh790rtij9AmGllqPtMLfhe2RSwD6Pn38V00uBCydV4m"]') </script> <devsite-a11y-announce></devsite-a11y-announce> </body> </html>