Flutter has become a popular framework for developing cross-platform mobile applications with a single codebase. While it provides a robust set of features for UI development, integrating a backend to store data is equally important. With its strong reputation for reliability and feature-richness, PostgreSQL is an excellent choice for a backend database.
In this blog, we will explore how to work with a PostgreSQL database in a Flutter project, including how to execute SQL queries and manage data effectively.
Before diving into the technical aspects, it's essential to understand why integrating PostgreSQL into a Flutter application can be beneficial. PostgreSQL databases offer more options for complex data storage and retrieval, and they are well-suited for server applications that require robust data management capabilities. Flutter, on the other hand, excels at building beautiful and responsive user interfaces. By combining the two, developers can create powerful, visually appealing, and data-rich applications.
To begin working with PostgreSQL in Flutter, you must first set up a PostgreSQL server. This involves installing PostgreSQL on your server or local machine, creating a new database, and configuring the necessary user access permissions. Ensure that your PostgreSQL server is running and you have the connection details such as host, port, username, and password.
This involves installing PostgreSQL on your server or local machine, creating a new database, and configuring the necessary user access permissions. For detailed installation instructions, refer to the official PostgreSQL installation documentation according to your operating system.
1CREATE DATABASE my_flutter_app; 2
1CREATE USER my_flutter_user WITH ENCRYPTED PASSWORD 'my_secure_password'; 2GRANT ALL PRIVILEGES ON DATABASE my_flutter_app TO my_flutter_user; 3
With the PostgreSQL server set up, integrating it into your Flutter project is the next step. This requires adding the necessary dependencies to your pubspec.yaml file.
1dependencies: 2 flutter: 3 sdk: flutter 4 postgres: ^latest_version 5
After adding the dependency, run flutter pub get to install the postgres package.
To connect to the PostgreSQL server from your Flutter application, you will need to use the postgres package. This package provides the necessary Dart classes and functions to establish a connection and execute queries.
1import 'package:postgres/postgres.dart'; 2
1final connection = PostgreSQLConnection( 2 'host', // Replace with your database host 3 port, // Replace with your database port 4 'database_name', // Replace with your database name 5 username: 'username', // Replace with your username 6 password: 'password', // Replace with your password 7); 8await connection.open(); 9
Once the connection is established, you can execute SQL queries to interact with your PostgreSQL database. You can perform operations such as insert, update, delete, and select to manage your data.
1var result = await connection.query( 2 'INSERT INTO users(name, email) VALUES (@name, @email)', 3 substitutionValues: { 4 'name': 'John Doe', 5 'email': 'john.doe@example.com' 6 } 7); 8
1List<List<dynamic>> results = await connection.query( 2 'SELECT * FROM users WHERE name = @name', 3 substitutionValues: { 4 'name': 'John Doe' 5 } 6); 7for (final row in results) { 8 print('Name: ${row[0]}, Email: ${row[1]}'); 9} 10
Handling errors and exceptions while executing queries or establishing a connection is crucial. This ensures that your Flutter application can gracefully handle unexpected issues and provide feedback to the user.
1try { 2 await connection.open(); 3 // Execute queries... 4} on PostgreSQLException catch (e) { 5 print('Error: ${e.toString()}'); 6} finally { 7 await connection.close(); 8} 9
Dart's async/await pattern is used extensively with databases to handle asynchronous operations. This pattern allows your Flutter application to perform database operations without blocking the main thread, ensuring a smooth user experience.
When working with PostgreSQL in a Flutter application, managing asynchronous operations is essential. Dart's async/await pattern helps execute database operations without blocking the UI, ensuring a responsive app.
1Future<void> addUser(String name, String email) async { 2 try { 3 await connection.open(); 4 await connection.query( 5 'INSERT INTO users(name, email) VALUES (@name, @email)', 6 substitutionValues: { 7 'name': name, 8 'email': email 9 } 10 ); 11 } catch (e) { 12 print('Error: ${e.toString()}'); 13 } finally { 14 await connection.close(); 15 } 16} 17
To retrieve data from a PostgreSQL database, you can execute select queries. The data returned from these queries can be used to populate your Flutter app's UI components.
1Future<List<User>> getUsers() async { 2 List<User> users = []; 3 try { 4 await connection.open(); 5 List<List<dynamic>> results = await connection.query('SELECT * FROM users'); 6 for (var row in results) { 7 User user = User(name: row[0], email: row[1]); 8 users.add(user); 9 } 10 } catch (e) { 11 print('Error: ${e.toString()}'); 12 } finally { 13 await connection.close(); 14 } 15 return users; 16} 17
You can execute update queries to update existing data in your PostgreSQL database. This allows you to modify data based on certain conditions or parameters.
1Future<void> updateUserEmail(String name, String newEmail) async { 2 try { 3 await connection.open(); 4 await connection.query( 5 'UPDATE users SET email = @newEmail WHERE name = @name', 6 substitutionValues: { 7 'name': name, 8 'newEmail': newEmail 9 } 10 ); 11 } catch (e) { 12 print('Error: ${e.toString()}'); 13 } finally { 14 await connection.close(); 15 } 16} 17
Similarly, you can execute delete queries to remove data from your PostgreSQL database. This operation should be handled with care to avoid accidental data loss.
1Future<void> deleteUser(String name) async { 2 try { 3 await connection.open(); 4 await connection.query( 5 'DELETE FROM users WHERE name = @name', 6 substitutionValues: { 7 'name': name 8 } 9 ); 10 } catch (e) { 11 print('Error: ${e.toString()}'); 12 } finally { 13 await connection.close(); 14 } 15} 16
Transactions are crucial when executing multiple queries that must be treated as a single atomic operation. Transactions ensure data integrity by either completing all operations successfully or rolling back changes in case of an error.
1Future<void> transferFunds(int fromUserId, int toUserId, double amount) async { 2 await connection.transaction((ctx) async { 3 await ctx.query( 4 'UPDATE accounts SET balance = balance - @amount WHERE user_id = @fromUserId', 5 substitutionValues: { 6 'fromUserId': fromUserId, 7 'amount': amount 8 } 9 ); 10 await ctx.query( 11 'UPDATE accounts SET balance = balance + @amount WHERE user_id = @toUserId', 12 substitutionValues: { 13 'toUserId': toUserId, 14 'amount': amount 15 } 16 ); 17 }); 18} 19
Working with PostgreSQL in a Flutter project requires understanding how to establish a connection, execute queries, and manage data. You can effectively integrate a PostgreSQL database into your Flutter applications by leveraging the “Postgres” package and Dart's async/await pattern.
Remember to handle errors gracefully and use transactions to maintain data integrity when necessary. With these practices, you can build robust and data-driven Flutter applications backed by the powerful PostgreSQL database.
Tired of manually designing screens, coding on weekends, and technical debt? Let DhiWise handle it for you!
You can build an e-commerce store, healthcare app, portfolio, blogging website, social media or admin panel right away. Use our library of 40+ pre-built free templates to create your first application using DhiWise.