{"id":19519033,"url":"https://github.com/bizz84/time_tracker_flutter_course","last_synced_at":"2025-04-06T01:10:48.024Z","repository":{"id":40667077,"uuid":"151738671","full_name":"bizz84/time_tracker_flutter_course","owner":"bizz84","description":"Source code for every lesson in the \"Flutter \u0026 Firebase: Build a Complete App for iOS \u0026 Android\" course on Udemy","archived":false,"fork":false,"pushed_at":"2021-03-20T21:30:40.000Z","size":501,"stargazers_count":400,"open_issues_count":8,"forks_count":167,"subscribers_count":23,"default_branch":"master","last_synced_at":"2025-03-30T00:09:33.033Z","etag":null,"topics":["firebase","flutter","udemy"],"latest_commit_sha":null,"homepage":"https://nnbd.me/ff-udemy","language":"Dart","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/bizz84.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2018-10-05T15:08:01.000Z","updated_at":"2025-03-18T05:09:29.000Z","dependencies_parsed_at":"2022-07-14T05:00:34.435Z","dependency_job_id":null,"html_url":"https://github.com/bizz84/time_tracker_flutter_course","commit_stats":null,"previous_names":[],"tags_count":220,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bizz84%2Ftime_tracker_flutter_course","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bizz84%2Ftime_tracker_flutter_course/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bizz84%2Ftime_tracker_flutter_course/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bizz84%2Ftime_tracker_flutter_course/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/bizz84","download_url":"https://codeload.github.com/bizz84/time_tracker_flutter_course/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247419861,"owners_count":20936012,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["firebase","flutter","udemy"],"created_at":"2024-11-11T00:15:58.124Z","updated_at":"2025-04-06T01:10:48.009Z","avatar_url":"https://github.com/bizz84.png","language":"Dart","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Flutter \u0026 Firebase Course | Code With Andrea\n\nThis repo contains the source code for my [Flutter \u0026 Firebase Course](https://nnbd.me/ff) on Udemy.\n\n## Running the project with Firebase\n\nTo use this project with Firebase, some configuration steps are required.\n\n- Create a new project with the Firebase console.\n- Add iOS and Android apps in the Firebase project settings.\n- On Android, use `com.codingwithflutter.time_tracker_flutter_course` as the package name.\n- then, [download and copy](https://firebase.google.com/docs/flutter/setup#configure_an_android_app) `google-services.json` into `android/app`.\n- On iOS, use `com.codingwithflutter.timeTrackerFlutterCourse` as the bundle ID.\n- then, [download and copy](https://firebase.google.com/docs/flutter/setup#configure_an_ios_app) `GoogleService-Info.plist` into `iOS/Runner`, and add it to the Runner target in Xcode.\n\nSee this page for full instructions:\n\n- [FlutterFire Overview](https://firebase.flutter.dev/docs/overview) \n\nThe setup steps are also explained in the course.\n\n## Course Diagrams\n\nAll diagrams shown in the course are available at this URL:\n\n- [Course Diagrams](https://www.sketch.com/s/a518d937-ff0c-4025-81c5-1cbdd3e0415e)\n\n## Course Contents\n\n### 1. Course Introduction\n\n1. Course Introduction\n2. Course Content\n3. App Overview\n4. Making the most of this course\n5. What is Flutter\n\n### 2. Introduction to Dart\n\n1. The Dart Language\n2. Introduction to Dartpad\n3. A simple program\n4. Variable declaration and initialization\n5. String interpolation\n6. Type inference with var\n7. Var and final\n8. The dynamic keyword\n9. Introduction to functions\n10. Function return types\n11. Optional parameters, nullability and default values\n12. Named parameters\n13. The arrow operator\n14. Introduction to classes\n15. Class constructors\n16. Instance methods\n17. Inheritance\n18. The super constructor\n19. The base Object class and the toString method\n20. Overriding the toString method\n21. Abstract classes\n22. More on abstract classes\n23. Using abstract classes with functions\n24. Computed properties\n25. Mixins\n26. Introduction to lists\n27. Introduction to maps\n28. Generics and type annotations\n29. If and else statements\n30. The ternary operator\n31. The while loop\n32. The for loop\n33. Closures and the fold method\n34. Enumerations\n35. Switch statements\n36. Wrap-up\n\n### 3. Flutter setup on macOS\n\n1. Flutter setup on macOS\n2. Setting the PATH variable\n3. Flutter doctor\n4. Xcode and iOS simulator setup\n5. Installing Android Studio\n6. Installing the Android emulator\n7. Running Flutter from the command line\n8. Flutter setup on Android Studio\n9. Installing Visual Studio Code\n\n### 4. Flutter setup on Windows\n\n1. Flutter setup on Windows\n2. Updating the path variable\n3. Flutter doctor\n4. Installing Android Studio\n5. Installing the Android emulator\n6. Running Flutter from the command line\n7. Flutter setup on Android Studio\n8. Installing Visual Studio Code\n\n### 5. Introduction to Flutter\n\n1. Creating a Flutter project with Android Studio\n2. A tour of the project folders\n3. Running the Android emulator and iOS simulator\n4. Overview of the Flutter counter app\n5. Hot reload and hot restart\n6. Introduction to widgets\n7. The MaterialApp widget\n8. The Scaffold widget\n9. The Flutter widget tree\n10. Stateless and stateful widgets\n11. Updating the counter with setState\n12. Wrap up\n\n### 6. Building Layouts\n\n1. Overview of the Time tracker app\n2. Switching between apps\n3. Writing the root widget of the app\n4. Adding the MaterialApp\n5. Adding some folders to our project\n6. Adding a sign-in page\n7. The ThemeData class\n8. The AppBar widget\n9. Preview of the SignInPage layout\n10. Adding a Column layout\n11. The CrossAxisAlignment property\n12. Code formatting with dartfmt\n13. Adding some boxes and extracting code into a method\n14. Private methods\n15. Adding some padding\n16. The MainAxisAlignment property\n17. Text, TextStyle and FontWeight\n18. Introduction to buttons\n19. Adding the first button\n20. Button callbacks explained\n21. Customising button colors\n22. MaterialColor explained\n23. Changing button shapes\n24. Making code reusable\n25. Creating a reusable custom RaisedButton\n26. Creating a reusable SignInButton\n27. Setting default values\n28. Making the button height configurable\n29. Adding the remaining buttons\n30. Adding logos: introduction\n31. Updating the pubspec.yaml file\n32. Image variants\n33. Adding an image inside a button\n34. Arranging widgets horizontally in a Row\n35. The Opacity widget\n36. Creating a custom SocialSignInButton\n37. The @required annotation\n38. Using assertions for better widget API design\n\n### 7. Firebase Authentication\n\n1. Local and remote authentication\n2. Introduction to Firebase\n3. Creating a Firebase project\n4. Configuring Firebase for Android\n5. Configuring Firebase for iOS\n6. Installing the firebase_core and firebase_auth packages\n7. Initializing the Firebase App\n8. Running on iOS and updating Cocoapods\n9. Futures, async and await\n10. Signing in anonymously with Firebase\n11. The FirebaseAuth singleton and private constructors\n12. Explaining the short-hand syntax for callbacks\n13. Error handling with try/catch\n\n### 8. Full Authentication Flow, State Management \u0026 Dependency Injection\n\n1. Preview of the sign-in and sign-out flow\n2. Creating a landing page widget\n3. Adding a Firebase User to the LandingPage\n4. Adding a callback to the SignInPage\n5. Hooking up the onSignIn callback\n6. Creating the home page\n7. Adding the sign-out functionality\n8. Hooking up the onSignOut callback\n9.  Retrieving the current user when the app starts\n10. Explaining global access and scoped access\n11. Creating the Auth class\n12. The abstract AuthBase class\n13. Using the Auth class\n14. Lifting state up and its drawbacks\n15. State Management \u0026 App Architecture\n\n### 9. Streams and StreamBuilder\n\n1. Introduction to Streams\n2. Streams in practice with DartPad\n3. Handling errors and closing streams\n4. The authStateChanges stream\n5. Listening to the authStateChanges stream\n6. Adding the StreamBuilder code\n7. More on StreamBuilder\n8. Refactoring the sign-in flows\n9. Wrap-up on Streams and StreamBuilder\n\n### 10. Google and Facebook sign-in\n\n1. Overview of the Firebase sign-in methods\n2. Enabling support for Google Sign In\n3. Adding Google Sign-In to the Auth class\n4. Hooking up Google Sign-In to our button\n5. Configuring Google Sign-In on iOS\n6. Google Sign-In flow explained\n7. Supporting Google Sign Out\n8. Testing Google Sign-In on Android\n9. Viewing registered users on the Firebase console\n10. Registering a Facebook App\n11. Enabling Facebook Sign-In on Firebase\n12. Installing the Facebook login package\n13. Enabling MultiDex support on Android\n14. Adding the Facebook Sign-In code\n15. Testing Facebook Sign-In on Android\n16. Facebook iOS setup in Xcode\n17. Testing Facebook Sign-In on iOS\n18. Accessing the user's data and privacy considerations\n\n### 11. Email \u0026 Password Sign-In + Handling Text Input\n\n1. Preview of the email \u0026 password sign-in page\n2. Creating the email \u0026 password sign-in page\n3. Passing the BuildContext across methods\n4. Introduction to navigation\n5. Adding a Card widget\n6. Adding the email and password text fields\n7. Adding the submit buttons\n8. Creating a FormSubmitButton widget\n9. Adding a TextEditingController\n10. Toggling the form type\n11. Adding the email \u0026 password authentication code\n12. Implementing the submit method\n13. Testing email \u0026 password sign-in\n14. Customising the email and password text fields\n15. Using FocusNode and FocusScope\n16. Disabling the submit button on empty email or password\n17. Adding a StringValidator class\n18. Adding an email and password validation mixin\n19. Showing an error text when the email or password are invalid\n20. Tweaking form submission\n21. Simulating a slow network with a delay\n22. Adding a loading state to our form\n23. Updating the email focus logic\n24. Fixing the vertical overflow on small screens\n25. Wrap-up\n\n### 12. Platform-aware widgets and dialogs\n\n1. Introduction to dialogs\n2. Showing a dialog\n3. Dismissing dialogs\n4. Platform-aware widgets on iOS, Android \u0026 more\n5. Adding a reusable showAlertDialog function\n6. Adding a sign-out confirmation dialog\n7. Dialog differences on Android and iOS\n\n### 13. Scoped Access with InheritedWidget and Provider\n\n1. Introduction to InheritedWidget\n2. Creating an AuthProvider\n3. Accessing the Auth object via the AuthProvider\n4. Adding the provider package\n5. Using the Provider class\n6. Wrap-up about scoped access and Provider\n\n### 14. Polishing the Authentication flows\n\n1. Module Introduction\n2. Creating better user-facing errors with FirebaseAuthException\n3. Creating a custom exception alert dialog\n4. Showing error alerts in the SignInPage\n5. Adding a loading state: overview\n6. Adding a loading state to the SignInPage\n7. Using the loading state in the SignInPage\n8. The dispose method\n\n### 15. BLoCs\n\n1. Introduction to state management with BLoCs\n2. The application layers\n3. BLoCs, sinks, streams, and asynchronous code\n4. Introduction to the SignInBloc\n5. Implementing a simple BLoC\n6. Adding a Bloc with Provider inside a static method\n7. Adding the StreamBuilder code\n8. Converting the SignInPage to a stateless widget\n9. The difference between Provider.of and Consumer\n10. Disposing BLoCs with Provider\n11. Adding authentication code to the SignInBloc\n12. Updating the SignInPage\n13. Fixing the BLoC submit method\n14. Summary on the BLoC basics\n15. Introduction to the email sign-in flow with BLoC\n16. Creating a model class for the EmailSignInForm\n17. Creating the EmailSignInBloc with a StreamController\n18. Updating the model\n19. Adding the BLoC submit method\n20. Setting up the EmailSignInFormBlocBased with Provider\n21. Refactoring the EmailSignInFormBlocBased widget by removing the state variables\n22. Moving the business logic to the BLoC class\n23. Moving more business logic to the model class\n24. The benefits of separation of concerns with BLoC\n25. Using stateful widgets with TextEditingControllers\n26. Considerations about performance\n27. Blocs and Services in the widget tree\n\n### 16. State Management with Provider\n\n1. Recap on State Management\n2. Introduction to ValueNotifier\n3. Adding a ValueNotifier with ChangeNotifierProvider\n4. Consumer and ChangeNotifierProvider explained\n5. Differences between BLoC/streams and ValueNotifier/ChangeNotifierProvider\n6. Introduction to ChangeNotifier\n7. Adding the EmailSignInChangeModel class\n8. Completing the EmailSignInChangeModel class\n9. Implementing the email sign-in form with ChangeNotifier\n10. Comparing ValueNotifier and ChangeNotifier\n11. Wrap up on State Management\n12. Wrap up on the Authentication Flows\n\n### 17. Databases and Cloud Firestore\n\n1. Overview of the time tracker app\n2. Database schema and SQL vs NoSQL\n3. Introduction to Cloud Firestore\n4. Documents and Collections\n5. Getting started with Firestore\n6. Designing a Database API with CRUD operations\n7. Managing private user data with Cloud Firestore\n8. Installing Cloud Firestore\n9. Renaming the HomePage to JobsPage\n10. Adding the Database class\n11. Adding the Database Provider\n12. Adding a FloatingActionButton\n13. Writing data to Firestore\n14. Defining a strongly-typed Job model class\n15. Defining a common API path class\n16. Adding a generic setData method\n17. Adding security rules\n18. Handling Firestore permissions errors\n19. Reading data from Firestore\n20. Reading and parsing Firestore data streams\n21. Adding a StreamBuilder to show a list of jobs\n22. Debugging the StreamBuilder code\n23. Firestore as a realtime database\n24. Adding a factory constructor to our model class\n25. Adding a generic method to read Firestore streams\n26. Adding a FirestoreService class\n27. Wrap-up on Cloud Firestore\n\n### 18. Working with Forms and Cloud Firestore\n\n1. Introduction to Forms with Cloud Firestore\n2. Adding a new job page\n3. The Placeholder widget\n4. Introduction to Form and TextFormField\n5. Validating and saving Form data\n6. Accessing the Database object with the correct BuildContext\n7. Saving jobs with a unique document ID\n8. Handling errors\n9. Enforcing unique job names\n10. Fixing the integer-parsing code\n11. Editing existing jobs: overview\n12. Adding a custom JobListTile\n13. Repurposing the AddJobPage for editing jobs\n14. Reading the documentID from Firestore\n15. Completing the code for editing jobs\n16. Wrap up on working with Forms\n\n### 19. Working with ListViews and multiple UI states\n\n1. Intro and multiple states of UI\n2. Adding an empty content widget\n3. Adding a reusable list items builder\n4. Using ListView.builder\n5. Using ListView.separated\n6. Deleting jobs from Firestore\n7. Adding swipe to delete support\n\n### 20. Working with Date \u0026 Time Pickers, more on Cloud Firestore\n\n1. Working with entries: overview\n2. Relational data \u0026 drawbacks of NoSQL databases\n3. Getting ready to add new files\n4. Adding the source files to the project\n5. Connecting the new code and updating the Firestore rules\n6. Fixing the EditJobPage navigation\n7. Overview of the JobEntriesPage\n8. Reading and writing entries with Firestore\n9. The EntryListItem widget (using InkWell and Expanded)\n10. Formatting dates and currencies with the Intl package\n11. Dart as UI: Spreads and Collection-if\n12. Using date pickers with stateful widgets\n13. Date and time input with a custom UI and DateTimePicker\n14. Updating the UI when a Job changes\n15. Wrap up and CupertinoDatePicker\n\n### 21. Bottom Navigation with the Cupertino widgets\n\n1. Introduction to bottom navigation\n2. Multiple navigation stacks\n3. Creating a HomePage with a selected tab\n4. Adding a CupertinoTabScaffold\n5. Testing the bottom navigation\n6. Adding the widget builders\n7. Replacing the FloatingActionButtons\n8. Moving the logout button to the AccountPage\n9. Presenting modal routes with the root navigator\n10. The CupertinoPageRoute\n11. Handling the Android back button with WillPopScope and navigator keys\n12. Adding pop-to-root navigation\n13. Wrap up on multiple navigators\n\n### 22. Advanced Stream Operations with RxDart\n\n1. Introduction to advanced stream operations\n2. Introduction to RxDart\n3. Observable.combineLatest and data transformations in the time tracker app\n4. Adding the source code for the new entries page\n5. Reviewing the UI code for the entries page\n6. Using combineLatest in practice\n7. Data manipulation in the EntriesBloc\n8. Wrap up on Observables\n9. Single subscription vs broadcast streams\n10. PublishSubject, ReplaySubject, BehaviorSubject\n11. Adding a BehaviorSubject to the EmailSignInBloc\n12. Wrap up and notes about local and remote state management\n\n### 23. Completing the Time Tracker App\n\n1. Completing the time tracker app: overview\n2. Accessing the User object in the AccountPage\n3. Adding an Avatar image\n4. Finishing the Avatar code\n5. Wrapping up the time tracker app\n\n### 24. Unit \u0026 Widget Tests with Mockito\n\n1. Introduction to writing tests\n2. Testing Flutter Apps\n3. Writing the first unit test\n4. Running tests\n5. Checking and fixing errors in tests\n6. Testing edge cases by writing and fixing failing tests\n7. Grouping tests together\n8. The setUp method and testing date formatting with locales\n9. The test lifecycle methods\n10. Completing the formatting tests\n11. Testing model classes\n12. hashCode and the == operator\n13. Adding a toString() method, wrap up on unit tests\n14. Introduction to widget tests\n15. Finding widgets and matcher arguments\n16. Testing widget callbacks\n17. Working with Acceptance Criteria\n18. Introduction to test mocks and mockito\n19. Injecting mock objects with Provider\n20. Verifying mock methods\n21. Working with keys, entering text and the pump() method\n22. Testing widget updates on state changes\n23. Completing the email sign-in tests\n24. Replacing Navigator.pop with a callback when the user signs in\n25. Updating the tests to handle the form callback\n26. Stubbing mock objects\n27. Recap on the email sign in forms and stubbing mocks\n28. Using widget tests with StreamBuilder\n29. Using StreamController inside tests\n30. Adding a Database builder to the Landing Page\n31. Test setup for the SignInPage\n32. Adding keys to custom widget classes\n33. Testing navigation\n34. The great thing about widget tests\n35. Testing ValueNotifier models\n36. Testing ChangeNotifier models\n37. Testing BloCs\n38. Comparing EmailSignInModel objects\n39. Testing streams in Blocs\n40. Wrap up on unit \u0026 widget tests\n\n### 25. Conclusion and Next Steps\n\n1. Conclusion and Next Steps\n\n---\n\n## [License: MIT](LICENSE.md)\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbizz84%2Ftime_tracker_flutter_course","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbizz84%2Ftime_tracker_flutter_course","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbizz84%2Ftime_tracker_flutter_course/lists"}