Flutter Course, Implementing Login Functionality 16.5

In this article, we will explore in detail how to implement a login feature using the Flutter framework. The login feature is a core element of the user authentication process and is essential in many applications. Properly implementing the login feature plays a significant role in enhancing user experience and strengthening security.

1. Overview of Flutter and Login Feature

Flutter is a UI toolkit developed by Google, enabling the creation of beautiful and fast applications for both iOS and Android platforms from a single codebase. In particular, Flutter’s widget-based architecture helps to easily build user interfaces and effectively improve user experiences.

2. Reasons for Needing a Login Feature

  • Security: A login process is necessary to protect user data and prevent unauthorized access.
  • Personalization: When users log in, the user experience can be personalized, and persistent data storage becomes possible.
  • Data Management: The login feature allows administrators to efficiently collect and manage user data.

3. Project Setup

First, you need to check if the Flutter environment is installed. If the Flutter SDK is installed, you can create a new Flutter project using the command below.

flutter create login_example

Navigate to the project folder.

cd login_example

4. Adding Required Packages

To implement the login feature, you need to add the http package to manage HTTP requests. Additionally, you might need the provider package for form validation. Open the pubspec.yaml file and add the packages below:

dependencies:
  flutter:
    sdk: flutter
  http: ^0.13.3
  provider: ^5.0.0

Run the command below to apply the changes.

flutter pub get

5. Building Basic UI

Now, let’s build the basic UI for the login screen. Please write the following code in the lib/main.dart file.

import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Login Example',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: LoginPage(),
    );
  }
}

class LoginPage extends StatefulWidget {
  @override
  _LoginPageState createState() => _LoginPageState();
}

class _LoginPageState extends State {
  final TextEditingController _emailController = TextEditingController();
  final TextEditingController _passwordController = TextEditingController();

  void _login() {
    // Login feature implementation is planned
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Login Page'),
      ),
      body: Padding(
        padding: const EdgeInsets.all(16.0),
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            TextField(
              controller: _emailController,
              decoration: InputDecoration(
                labelText: 'Email',
                border: OutlineInputBorder(),
              ),
            ),
            SizedBox(height: 16.0),
            TextField(
              controller: _passwordController,
              decoration: InputDecoration(
                labelText: 'Password',
                border: OutlineInputBorder(),
              ),
              obscureText: true,
            ),
            SizedBox(height: 16.0),
            ElevatedButton(
              onPressed: _login,
              child: Text('Login'),
            ),
          ],
        ),
      ),
    );
  }
}

6. Implementing Login Functionality

We will explore how to handle user login information in a mobile application and how to request that information from a server. Add the following code to the _login method:

import 'dart:convert';
import 'package:http/http.dart' as http;

void _login() async {
  String email = _emailController.text;
  String password = _passwordController.text;

  // Sending POST request to the server
  final response = await http.post(
    Uri.parse('https://example.com/api/login'),
    headers: {
      'Content-Type': 'application/json',
    },
    body: jsonEncode({
      'email': email,
      'password': password,
    }),
  );

  if (response.statusCode == 200) {
    // Login successful
    final data = jsonDecode(response.body);
    // Handle user information (e.g., save token)
    print('Login successful: ${data['token']}');
  } else {
    // Login failed
    print('Login failed: ${response.body}');
  }
}

7. Error Handling and User Feedback

If the login fails, provide an appropriate error message to the user. You can use the alert dialog box to display an error message. You can add the following code to show a message upon login failure:

if (response.statusCode != 200) {
  _showErrorDialog('Login failed. Please check your email or password.');
}

void _showErrorDialog(String message) {
  showDialog(
    context: context,
    builder: (ctx) => AlertDialog(
      title: Text('Error'),
      content: Text(message),
      actions: [
        TextButton(
          onPressed: () => Navigator.of(ctx).pop(),
          child: Text('OK'),
        ),
      ],
    ),
  );
}

8. Adding Form Validation

It is advisable to add field validation to ensure that users enter valid email and password. You can validate input using Flutter’s Form and TextFormField widgets.

final _formKey = GlobalKey();

@override
Widget build(BuildContext context) {
  return Form(
    key: _formKey,
    child: Column(
      ...
      children: [
        TextFormField(
          controller: _emailController,
          validator: (value) {
            if (value == null || value.isEmpty) {
              return 'Please enter your email.';
            }
            return null;
          },
          ...
        ),
        TextFormField(
          controller: _passwordController,
          validator: (value) {
            if (value == null || value.isEmpty) {
              return 'Please enter your password.';
            }
            return null;
          },
          ...
        ),
        ElevatedButton(
          onPressed: () {
            if (_formKey.currentState!.validate()) {
              _login();
            }
          },
          child: Text('Login'),
        ),
      ],
    ),
  );
}

9. Session Management

To manage the user’s session after login, you can store the token of the logged-in user in local storage. Using the shared_preferences package allows for easy storage. Implement session management as follows:

import 'package:shared_preferences/shared_preferences.dart';

void _login() async {
  // ... existing code omitted ...
  
  if (response.statusCode == 200) {
    final data = jsonDecode(response.body);
    // Save token
    SharedPreferences prefs = await SharedPreferences.getInstance();
    await prefs.setString('token', data['token']);
    print('Login successful: ${data['token']}');
  }

10. Implementing Logout Functionality

Add a logout feature so that users can log out. During logout, end the session and remove the stored token.

void _logout() async {
  SharedPreferences prefs = await SharedPreferences.getInstance();
  await prefs.remove('token');
  print('Logged out successfully.');
}

11. Additional Security Considerations

When implementing the login feature, consider the following security principles:

  • HTTPS: Login requests should always use HTTPS protocol for encryption.
  • Password Storage: User passwords should be stored encrypted and should not be exposed directly.
  • Two-Factor Authentication: Consider implementing Two-Factor Authentication (MFA) for additional security.

12. Conclusion

In this tutorial, we explored in detail how to implement a login feature using Flutter. User authentication is an important part of applications and should be designed with security and user experience in mind. Built on the login feature, we hope to create applications that manage user data securely and efficiently.

We will cover more Flutter-related topics in future tutorials, so please stay tuned. Thank you!

Flutter Course: Creating a Member Registration Page and Implementing Sign-Up Functionality

Hello! Today we will learn how to create a sign-up page using Flutter and implement the sign-up functionality. User authentication is a very important aspect of mobile applications, and the sign-up feature is the starting point. In this tutorial, we will create a form that accepts the user’s email, password, and additional information, and learn how to connect it with Firebase Authentication to create a valid account.

1. Prerequisites

First, you need to prepare the following for learning:

  • Flutter SDK must be installed. Refer to the official website for installation instructions.
  • A Firebase account for the relevant project is needed. Sign up on the Firebase console and create a project.
  • You need Android Studio or another code editor.
  • You should install the related packages for Flutter. Add the necessary Flutter dependencies for Firebase and HTTP requests.

2. Firebase Project Setup

To use the sign-up functionality with Firebase, you need to set up a Firebase project. Follow the steps below to set it up.

  1. Log in to the Firebase console and create a new project.
  2. Go to the ‘Authentication’ menu and enable the email/password option under ‘Sign-in methods’.
  3. Register the Android/iOS app through ‘App registration’ and download the necessary Google services configuration file.

3. Creating a Flutter Project

To create a new Flutter project, enter the following command in your terminal:

flutter create sign_up_app

After moving to the project folder, run the following commands to install the required packages:

cd sign_up_app
flutter pub add firebase_core
flutter pub add firebase_auth

4. Initializing Firebase

Now you need to initialize Firebase to use it in your Flutter app. Open the lib/main.dart file and add the following code:

import 'package:flutter/material.dart';
import 'package:firebase_core/firebase_core.dart';

void main() async {
    WidgetsFlutterBinding.ensureInitialized();
    await Firebase.initializeApp();
    runApp(MyApp());
}

class MyApp extends StatelessWidget {
    @override
    Widget build(BuildContext context) {
        return MaterialApp(
            home: SignUpPage(), // Set to point to sign-up page
        );
    }
}

5. Designing the Sign-Up Page UI

The sign-up page consists of a form where users can enter their email and password. Add the following code to design the sign-up page UI.

class SignUpPage extends StatefulWidget {
    @override
    _SignUpPageState createState() => _SignUpPageState();
}

class _SignUpPageState extends State {
    final _emailController = TextEditingController();
    final _passwordController = TextEditingController();

    @override
    Widget build(BuildContext context) {
        return Scaffold(
            appBar: AppBar(
                title: Text('Sign Up'),
            ),
            body: Padding(
                padding: const EdgeInsets.all(16.0),
                child: Column(
                    children: [
                        TextField(
                            controller: _emailController,
                            decoration: InputDecoration(labelText: 'Email'),
                        ),
                        TextField(
                            controller: _passwordController,
                            decoration: InputDecoration(labelText: 'Password'),
                            obscureText: true,
                        ),
                        SizedBox(height: 20),
                        ElevatedButton(
                            onPressed: _signUp,
                            child: Text('Sign Up'),
                        ),
                    ],
                ),
            ),
        );
    }

    void _signUp() {
        // Implement sign-up logic here.
    }
}

6. Implementing Sign-Up Functionality

Implement the logic to create an account by processing the email and password entered by the user through Firebase Authentication. Add the following code to the _signUp method:

void _signUp() async {
    final email = _emailController.text;
    final password = _passwordController.text;
    
    try {
        UserCredential userCredential = await FirebaseAuth.instance.createUserWithEmailAndPassword(
            email: email,
            password: password,
        );
        // You can perform additional tasks after successful sign-up.
        print("Sign-up successful: ${userCredential.user.uid}");
    } catch (e) {
        print("Sign-up failed: $e");
        ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text('Sign-up failed')));
    }
}

7. Error Handling and Validation

It is necessary to handle errors for the sign-up feature in case the user inputs incorrect information. You can check whether the entered email format is correct and the minimum length of the password to create a more robust feature.

void _signUp() async {
    final email = _emailController.text;
    final password = _passwordController.text;  
    
    if (!_isEmailValid(email) || !_isPasswordValid(password)) {
        ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text('Invalid input')));
        return;
    }

    try {
        UserCredential userCredential = await FirebaseAuth.instance.createUserWithEmailAndPassword(
            email: email,
            password: password,
        );
        print("Sign-up successful: ${userCredential.user.uid}");
        // You can navigate to the next page or perform other actions.
    } catch (e) {
        print("Sign-up failed: $e");
        ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text('Sign-up failed: ${e.toString()}')));
    }
}

bool _isEmailValid(String email) {
    return RegExp(r'^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$').hasMatch(email);
}

bool _isPasswordValid(String password) {
    return password.length >= 6;
}

8. User Feedback

After completing the sign-up functionality, it’s good to consider providing the user with success or failure messages. You can use the SnackBar used in the code above to provide simple feedback.

9. Conclusion and Next Steps

Through this tutorial, you learned how to create a simple sign-up page using Flutter and how to create user accounts through Firebase Authentication. Now you can incorporate these features into your application to allow more users to access it.

As the next step, it would be good to learn more advanced features such as implementing user login functionality or integrating social login. Thank you!

If you found this article helpful, please like and comment!

Flutter Course: 16.3 Installing Firebase Auth Package and Setting Up Email Authentication

Hello, Flutter developers! In this tutorial, we will explore in detail how to set up user authentication via Email using Firebase. Firebase offers a variety of services including databases, hosting, storage, and particularly Firebase Auth, which is very useful for handling user authentication. In this tutorial, we will guide you step-by-step on how to install the Firebase Auth package and set up email authentication.

1. Create a Firebase Project

To use Firebase, you first need to create a project in the Firebase console. Follow the steps below to create a project.

  1. Access the Firebase console.
  2. Click the ‘Add Project’ button in the top right corner.
  3. Enter the project name, select the Google Analytics settings, and then click ‘Create Project’.

2. Set up Firebase Auth

Once the project is created, you need to set up Firebase Auth.

  1. Click on ‘Authentication’ in the left menu.
  2. Navigate to the ‘Sign-in method’ tab.
  3. Find and enable the Email/Password sign-in option.

3. Create a Flutter Project

Now, let’s create a Flutter project. Use the command below to create a new Flutter project.

flutter create firebase_auth_example

Navigate to the project directory.

cd firebase_auth_example

4. Install Firebase Core and Auth Packages

You need to add the necessary packages to use Firebase in Flutter. Open the ‘pubspec.yaml’ file and add the following dependencies.

dependencies:
  flutter:
    sdk: flutter
  firebase_core: ^2.0.0
  firebase_auth: ^5.0.0

Now, enter the command below to install the packages.

flutter pub get

5. Initialize Firebase

After installing the packages, you need to initialize Firebase. Open the ‘main.dart’ file and add the following code.

import 'package:flutter/material.dart';
import 'package:firebase_core/firebase_core.dart';

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await Firebase.initializeApp();
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Firebase Auth Example',
      home: HomeScreen(),
    );
  }
}

6. Create Login UI

Let’s build a login screen for email authentication. Add the ‘HomeScreen’ widget and include fields for email and password input as well as a login button.

import 'package:firebase_auth/firebase_auth.dart';

// ...

class HomeScreen extends StatefulWidget {
  @override
  _HomeScreenState createState() => _HomeScreenState();
}

class _HomeScreenState extends State {
  final FirebaseAuth _auth = FirebaseAuth.instance;
  final TextEditingController _emailController = TextEditingController();
  final TextEditingController _passwordController = TextEditingController();

  void signIn(String email, String password) async {
    try {
      UserCredential userCredential = await _auth.signInWithEmailAndPassword(
        email: email,
        password: password,
      );
      print('User signed in: ${userCredential.user}');
    } on FirebaseAuthException catch (e) {
      print('Failed to sign in: $e');
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Login'),
      ),
      body: Padding(
        padding: const EdgeInsets.all(16.0),
        child: Column(
          children: [
            TextField(
              controller: _emailController,
              decoration: InputDecoration(labelText: 'Email'),
            ),
            TextField(
              controller: _passwordController,
              decoration: InputDecoration(labelText: 'Password'),
              obscureText: true,
            ),
            SizedBox(height: 20),
            ElevatedButton(
              onPressed: () {
                signIn(_emailController.text, _passwordController.text);
              },
              child: Text('Login'),
            ),
          ],
        ),
      ),
    );
  }
}

7. Request Email Verification

After signing in, the user can request email verification. Add the code as below.

void sendVerificationEmail(User user) async {
  if (!user.emailVerified) {
    await user.sendEmailVerification();
    print('Verification email sent to ${user.email}');
  }
}

// Add this at the end of the signIn method.
if (userCredential.user != null) {
  sendVerificationEmail(userCredential.user!);
}

8. Check Email Verification

Add logic to check if the user has verified their email. You can verify whether the user checked their email after logging in.

void checkEmailVerification() async {
  User? user = _auth.currentUser;
  await user?.reload();
  user = _auth.currentUser;
  if (user != null && user.emailVerified) {
    print('Email verified!');
    // Logic to navigate as a verified user can be added.
  } else {
    print('Email not verified yet.');
  }
}

// Add at the end of the signIn method.
checkEmailVerification();

9. Complete Code

Finally, the complete main.dart code is as follows.

import 'package:flutter/material.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:firebase_auth/firebase_auth.dart';

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await Firebase.initializeApp();
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Firebase Auth Example',
      home: HomeScreen(),
    );
  }
}

class HomeScreen extends StatefulWidget {
  @override
  _HomeScreenState createState() => _HomeScreenState();
}

class _HomeScreenState extends State {
  final FirebaseAuth _auth = FirebaseAuth.instance;
  final TextEditingController _emailController = TextEditingController();
  final TextEditingController _passwordController = TextEditingController();

  void signIn(String email, String password) async {
    try {
      UserCredential userCredential = await _auth.signInWithEmailAndPassword(
        email: email,
        password: password,
      );
      sendVerificationEmail(userCredential.user!);
      checkEmailVerification();
    } on FirebaseAuthException catch (e) {
      print('Failed to sign in: $e');
    }
  }

  void sendVerificationEmail(User user) async {
    if (!user.emailVerified) {
      await user.sendEmailVerification();
      print('Verification email sent to ${user.email}');
    }
  }

  void checkEmailVerification() async {
    User? user = _auth.currentUser;
    await user?.reload();
    user = _auth.currentUser;
    if (user != null && user.emailVerified) {
      print('Email verified!');
    } else {
      print('Email not verified yet.');
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Login'),
      ),
      body: Padding(
        padding: const EdgeInsets.all(16.0),
        child: Column(
          children: [
            TextField(
              controller: _emailController,
              decoration: InputDecoration(labelText: 'Email'),
            ),
            TextField(
              controller: _passwordController,
              decoration: InputDecoration(labelText: 'Password'),
              obscureText: true,
            ),
            SizedBox(height: 20),
            ElevatedButton(
              onPressed: () {
                signIn(_emailController.text, _passwordController.text);
              },
              child: Text('Login'),
            ),
          ],
        ),
      ),
    );
  }
}

10. Conclusion

Now you have learned how to set up email authentication using Flutter and Firebase. Requesting email verification is an important feature to enhance user experience. Please utilize this feature for additional security. In the next tutorial, we will cover how to implement social login. Thank you!

Flutter Course: 16.2 Integrating the Login App with Firebase Project

In this course, we will learn how to create a login app using Flutter and integrate it with Google’s Firebase backend. By the end of the course, you will have created a basic app that allows users to log in with their email and password. Firebase is a tool that provides various features, including authentication, data storage, and hosting, for applications. Many developers use this service to develop apps quickly and easily.

1. Preparation

First, we need to prepare to use Flutter and Firebase. Please check the following requirements:

  • Programming environment: Flutter SDK must be installed.
  • You need to create a Firebase account.
  • Prepare an IDE (e.g., Visual Studio Code or Android Studio).
  • You need to set up a project in the Firebase console to use Firebase Authentication.

2. Create a Flutter Project

First, we create a new Flutter project. In the terminal, enter the following command:

flutter create login_app

Now, let’s navigate to the created directory and open the project:

cd login_app

3. Set Up Firebase

3.1 Create a New Project in Firebase Console

1. Log in to the Firebase console. Firebase Console

2. Click “Add Project” to create a new project.

3. Complete the project’s name and initial settings.

3.2 Activate Firebase Authentication

1. From the dashboard of the newly created project, select “Authentication” from the menu.

2. Go to the “Sign-in Method” tab and enable “Email/Password” login.

3.3 Register the Android App

1. Click the Android icon on the dashboard to register the Android app.

2. Enter the package name; you do not need to input the SHA-1 key for testing purposes.

3. Click the “Register” button.

4. Download the google-services.json file and add it to the android/app directory.

3.4 Install Firebase CLI

The Firebase CLI tool makes it easy to perform Firebase-related tasks. Install Firebase CLI with the following command:

npm install -g firebase-tools

4. Integrate Flutter with Firebase

4.1 Modify pubspec.yaml File

Open the pubspec.yaml file in your Flutter project, and add the following packages:


dependencies:
  flutter:
    sdk: flutter
  firebase_core: latest_version
  firebase_auth: latest_version

After adding the packages, install them with the following command:

flutter pub get

4.2 Initialize Firebase

Initialize Firebase in the main.dart file. To initialize the Firebase app, add the following code:


import 'package:firebase_core/firebase_core.dart';

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await Firebase.initializeApp();
  runApp(MyApp());
}

5. Implement Login UI

Now it’s time to implement the login screen. We will use StatefulWidget to create a basic login screen.


import 'package:flutter/material.dart';
import 'package:firebase_auth/firebase_auth.dart';

class LoginScreen extends StatefulWidget {
  @override
  _LoginScreenState createState() => _LoginScreenState();
}

class _LoginScreenState extends State {
  final _emailController = TextEditingController();
  final _passwordController = TextEditingController();
  String? _errorMessage;

  Future _login() async {
    try {
      await FirebaseAuth.instance.signInWithEmailAndPassword(
        email: _emailController.text.trim(),
        password: _passwordController.text.trim(),
      );
      // Handle after successful login
    } on FirebaseAuthException catch (e) {
      setState(() {
        _errorMessage = e.message;
      });
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Login')),
      body: Padding(
        padding: const EdgeInsets.all(16.0),
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            TextField(
              controller: _emailController,
              decoration: InputDecoration(labelText: 'Email'),
            ),
            TextField(
              controller: _passwordController,
              obscureText: true,
              decoration: InputDecoration(labelText: 'Password'),
            ),
            SizedBox(height: 20),
            ElevatedButton(
              onPressed: _login,
              child: Text('Login'),
            ),
            if (_errorMessage != null)
              Text(
                _errorMessage!,
                style: TextStyle(color: Colors.red),
              ),
          ],
        ),
      ),
    );
  }
}

6. Test the App

Once you have completed the above code, try running the app. You can use the Android Emulator provided by Flutter or a physical device. Enter the following command in the terminal to run the app:

flutter run

7. Additional Features

In addition to the login feature, you can add the following functionalities for better user convenience:

  • Sign-up feature
  • Password reset feature
  • Social login feature (Google, Facebook, etc.)

8. Conclusion

In this course, we learned how to create a login app integrated with Firebase using Flutter. Firebase is a useful backend solution that provides various features such as databases and storage, allowing for the implementation of a wider range of functionalities. We hope your login app works great!

9. References

Flutter Course: 15.8 Fetching Real-Time Weather Data

In today’s lecture, we will discuss how to fetch real-time weather data using Flutter. Weather applications are one of the projects that many developers create as their first project, providing an interesting experience of easily fetching weather data via an API and displaying it in the UI. In this lecture, we will learn about various topics such as API calls, JSON data parsing, and utilizing StatefulWidget.

Minimum Requirements

  • You should have Flutter SDK and development environment installed.
  • A basic understanding of the Dart language and Flutter framework is required.
  • We will use Pub.dev to utilize external libraries.

1. Project Setup

To create a new Flutter project, execute the following command:

flutter create weather_app

After navigating into the created project folder, open the lib/main.dart file.

2. Installing Required Packages

We will use the HTTP package to fetch weather data. Add the following dependency to the pubspec.yaml file:

dependencies:
  http: ^0.13.3

After saving the changes, install the package with the following command:

flutter pub get

3. Selecting API and Obtaining Key

In this lecture, we will use the OpenWeatherMap API to fetch real-time weather data. Follow these steps to use the API.

  1. Go to the OpenWeatherMap website and create an account.
  2. Generate an API key and make a note of it.

4. Creating Weather Data Model

It is necessary to understand the structure of the weather data returned by the API and convert it to a Dart model. Here is a simple model to represent weather data:

class Weather {
  final String description;
  final double temperature;

  Weather({required this.description, required this.temperature});

  factory Weather.fromJson(Map json) {
    return Weather(
      description: json['weather'][0]['description'],
      temperature: json['main']['temp'],
    );
  }
}

5. Fetching Data: HTTP GET Request

Now, let’s create an HTTP GET request to fetch weather data from the API. Add the following function to the main file:

import 'dart:convert';
import 'package:http/http.dart' as http;

Future fetchWeather(String city) async {
  final String apiKey = 'YOUR_API_KEY'; // Change to your API key
  final response = await http.get(Uri.parse('https://api.openweathermap.org/data/2.5/weather?q=$city&appid=$apiKey&units=metric'));

  if (response.statusCode == 200) {
    return Weather.fromJson(json.decode(response.body));
  } else {
    throw Exception('Failed to load weather data');
  }
}

6. Building the UI

Now, let’s create the user interface. Build a simple UI that takes user input for the city name and displays weather information:

import 'package:flutter/material.dart';

void main() {
  runApp(WeatherApp());
}

class WeatherApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Weather App',
      home: WeatherHomePage(),
    );
  }
}

class WeatherHomePage extends StatefulWidget {
  @override
  _WeatherHomePageState createState() => _WeatherHomePageState();
}

class _WeatherHomePageState extends State {
  final TextEditingController _controller = TextEditingController();
  Weather? _weather;
  String? _errorMessage;

  void _getWeather() async {
    try {
      final weather = await fetchWeather(_controller.text);
      setState(() {
        _weather = weather;
        _errorMessage = null;
      });
    } catch (e) {
      setState(() {
        _errorMessage = e.toString();
      });
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Weather App'),
      ),
      body: Padding(
        padding: const EdgeInsets.all(16.0),
        child: Column(
          children: [
            TextField(
              controller: _controller,
              decoration: InputDecoration(labelText: 'Enter city name'),
            ),
            SizedBox(height: 10),
            ElevatedButton(
              onPressed: _getWeather,
              child: Text('Get Weather'),
            ),
            SizedBox(height: 20),
            if (_errorMessage != null)
              Text(
                _errorMessage!,
                style: TextStyle(color: Colors.red),
              ),
            if (_weather != null) ...[
              Text('Temperature: ${_weather!.temperature}°C'),
              Text('Description: ${_weather!.description}'),
            ],
          ],
        ),
      ),
    );
  }
}

7. Running the App

Once all the code is written, run the app to check if it works. You can start the app using the following command in the terminal:

flutter run

Enter the city name and click the ‘Get Weather’ button to display the real-time weather information for that city.

8. Future Improvements

This application provides only basic weather information. Consider the following improvements:

  • Add GPS functionality to get weather for the current location
  • Display more weather information (humidity, pressure, etc.)
  • Enhance the UI for a better user experience
  • Support offline mode

Conclusion

In this lecture, we created a simple application to fetch real-time weather data using Flutter. We learned how to use the weather API and how to obtain data from it. We hope you lay the foundation to progress to more complex applications.

If you have any questions or comments, feel free to leave them in the comments!