Unit 4 Flutter-1
Unit 4 Flutter-1
In this guide, we’ll dive into networking in Flutter, covering everything from setting up your
first network request to handling complex scenarios like error handling and JSON parsing.
With the rise of real-time data-driven apps, networking is essential for mobile developers.
Flutter supports HTTP networking, enabling developers to build applications that interact
with APIs, databases, and other web services. Whether you’re developing a social media
app, a weather app, or an e-commerce platform, networking is the backbone of these apps’
functionality.
In Flutter, networking is made easier through libraries http, which provide a simple API for
performing HTTP requests and handling responses. Let's explore how you can start with
networking in Flutter.
To fetch data from a web server in Flutter, you can use the http package. This package
simplifies the process of making network requests and handling responses. Below is a basic
example of how to use it:
This example sends a GET request to a server, waits for the response, and decodes the JSON
data. If the request fails, an exception is thrown.
Tip: Always check the status code of the response to handle potential errors.
In this code, we send a POST request with the necessary headers and body.
The jsonEncode function ensures that the data is properly formatted before sending it.
Tip: Be mindful of encoding data to JSON and setting the correct headers for the request.
When working with APIs, responses can come in various formats — JSON, XML, or even raw
HTML. JSON is the most commonly used format for API responses, and Flutter makes it easy
to handle such data.
To convert the JSON response into Dart objects, you can use the dart:convert package, which
provides functions like jsonDecode and jsonEncode. This is particularly useful when dealing
with structured data like lists and maps.
This parses the JSON response string into a Dart object, allowing you to access and
manipulate the data easily.
Tip: Make sure to handle any errors that might occur during parsing, especially when dealing
with large or complex datasets.
Networking operations often encounter errors due to connectivity issues, server problems,
or invalid requests. It’s crucial to handle these errors gracefully to improve user experience.
In Flutter, you can manage network errors using try-catch blocks or handling error codes
directly from the HTTP response:
try {
final response = await http.get(Uri.parse('https://jsonplaceholder.typicode.com/posts'));
if (response.statusCode == 200) {
// Success
} else {
throw Exception('Failed to load data');
}
} catch (e) {
// Handle error
print('Error: $e');
}
By handling mistakes like this, you can ensure your app doesn’t crash and provide helpful
feedback to users in case of failure.
Learn more about handling errors and optimizing networking in Flutter on Blup.
Here are some best practices to follow when working with networking in Flutter:
3. Use Efficient Data Formats: JSON is lightweight and easy to parse, making it ideal for
mobile networking.
4. Keep Your UI Responsive: Avoid blocking the UI thread during network requests. Use
Flutter’s built-in widgets FutureBuilder to update the UI asynchronously.
5. Follow RESTful Principles: For server communication, ensure your network calls
adhere to RESTful standards, utilizing proper HTTP methods and status codes.
In this article, we are going to learn how to implement a custom class to store and access
values stored in shared preferences.
Suppose you want to keep track of user authentication. You want to store the information
about the user authentication status so that the user does not need to authenticate each
time he opens the app. In this case, we can store authentication information like status,
access token, and refresh token in the shared preferences and use them whenever we need
across the application.
In this example, we are going to see how we can store different type of data in the shared
preferences.
cd flutter_sharedpref
Using this the flutter project will be created. The structure of the project is given below
dependencies:
flutter:
sdk: flutter
shared_preferences: ^2.0.6
after changing pubspec.yaml file, Run flutter pub get to install the dependencies.
import 'package:shared_preferences/shared_preferences.dart';
Let's save different types of data like int, double, String, Boolean, and list.
prefs.setInt('intValue', 18);
prefs.setDouble('doubleValue', 3.14159265359);
prefs.setBool('boolValue', true);
Reading data in share preferences is as easy as storing. we need key to pass to shared
preferences to get the value of data stored.
prefs.setInt('intValue', 18);
return doubleValue;
return stringValue;
return boolValue;
}
return listData.isNotEmpty;
Note : As you can notice we have used null-aware operator. this will ensure that when the
value from shared preferences is empty, the value on the right hand side of this operator
gets assigned to variable.
Syntax
expression2 => Is the second expression, which is the default value to be used if expression1
is null.
Now we have basic idea of how to implement shared preferences in flutter, Let's see how
can we make a custom class of shared preferences.
Create a class and name it as per your need. in this case SharedPreferencesManager.
class SharedPreferencesManager {}
In this step all you need to do is brainstorm your application idea and get the requirements
for which data or values need to store in the shared preferences. accordingly you need to
declare the keys, for example. In authentications scenario we might need to store user-id,
access token, etc. so the keys would be the "user_id", "access_token" .
Declaring the methods which will help store the shared preferences and retrieve them when
method is called, All the methods which
prefs.setInt(intKey, intData);
prefs.setDouble(doubleKey, doubleData);
prefs.setString(stringKey, stringData);
prefs.setBool(boolKey, boolData);
return prefs.getInt(intKey) ?? 0;
as we can see we have declared methods to store shared preferences as well as read shared
preferences. using the object of this class we can easily call the methods to read and write
data.
Step 4 : Storing Data in Shared Preferences using Custom class Object
prefManager.addIntToPref(10);
prefManager.addDoubleToPref(10.5);
prefManager.addStringToPref('Hello World');
prefManager.addBoolToPref(true);
Step 5 : Retrieving Data from Shared Preferences Using Custom class Object
Similarly, we will now call the methods to read the data from shared preferences. we are
assigning these values or data to variables hence we can use them later. for this we are
making one method and inside it reading all the data.
int intValue = 0;
as we can see , readData() method is used to read data by calling methods declared in
custom class, and assigned values to declared variables.
import 'package:flutter/material.dart';
import 'package:flutter_sharedpref/my_home_page.dart';
void main() {
runApp(const MyApp());
const MyApp({super.key});
@override
return MaterialApp(
debugShowCheckedModeBanner: false,
theme: ThemeData(
primarySwatch: Colors.blue,
),
);
}
NoSQL, or “Not Only SQL,” is a database management system (DBMS) designed to handle
large volumes of unstructured and semi-structured data. Unlike traditional relational databases
that use tables and pre-defined schemas, NoSQL databases provide flexible data models and
support horizontal scalability, making them ideal for modern applications that require real-
time data processing.
In this article, we will explain what NoSQL databases are, their types, key features, advantages,
disadvantages, and use cases. We will also compare NoSQL with SQL databases, discuss when to
use NoSQL, and highlight some of the most popular NoSQL databases used today.
1. High scalability: NoSQL databases use sharding for horizontal scaling. Partitioning of data
and placing it on multiple machines in such a way that the order of the data is preserved is
sharding. Vertical scaling means adding more resources to the existing machine whereas
horizontal scaling means adding more machines to handle the data. Vertical scaling is not that
easy to implement but horizontal scaling is easy to implement. Examples of horizontal scaling
databases are MongoDB, Cassandra, etc. NoSQL can handle a huge amount of data because of
scalability, as the data grows NoSQL scalesThe auto itself to handle that data in an efficient
manner.
2. Flexibility: NoSQL databases are designed to handle unstructured or semi-structured data,
which means that they can accommodate dynamic changes to the data model. This makes
NoSQL databases a good fit for applications that need to handle changing data requirements.
3. High availability: The auto, replication feature in NoSQL databases makes it highly available
because in case of any failure data replicates itself to the previous consistent state.
4. Scalability: NoSQL databases are highly scalable, which means that they can handle large
amounts of data and traffic with ease. This makes them a good fit for applications that need to
handle large amounts of data or traffic
5. Performance: NoSQL databases are designed to handle large amounts of data and traffic,
which means that they can offer improved performance compared to traditional relational
databases.
6. Cost-effectiveness: NoSQL databases are often more cost-effective than traditional
relational databases, as they are typically less complex and do not require expensive hardware
or software.
7. Agility: Ideal for agile development.
Disadvantages of NoSQL
1. Lack of standardization: There are many different types of NoSQL databases, each with its
own unique strengths and weaknesses. This lack of standardization can make it difficult to
choose the right database for a specific application
2. Lack of ACID compliance: NoSQL databases are not fully ACID-compliant, which means that
they do not guarantee the consistency, integrity, and durability of data. This can be a
drawback for applications that require strong data consistency guarantees.
3. Narrow focus: NoSQL databases have a very narrow focus as it is mainly designed for
storage but it provides very little functionality. Relational databases are a better choice in the
field of Transaction Management than NoSQL.
4. Open-source: NoSQL is an databaseopen-source database. There is no reliable standard for
NoSQL yet. In other words, two database systems are likely to be unequal.
5. Lack of support for complex queries: NoSQL databases are not designed to handle
complex queries, which means that they are not a good fit for applications that require
complex data analysis or reporting.
6. GUI is not available: GUI mode tools to access the database are not flexibly available in the
market.
7. Backup: Backup is a great weak point for some NoSQL databases like MongoDB. MongoDB
has no approach for the backup of data in a consistent manner.
8. Large document size: Some database systems like MongoDB and CouchDB store data in
JSON format. This means that documents are quite large (BigData, network bandwidth, speed),
and having descriptive key names actually hurts since they increase the document size.
Step 1: Add Dependencies
In your pubspec.yaml file, add the sqflite and path packages under dependencies:
yaml
CopyEdit
dependencies:
flutter:
sdk: flutter
sqflite: ^2.2.5
path: ^1.8.3
Then, run:
bash
CopyEdit
dart
CopyEdit
import 'package:sqflite/sqflite.dart';
import 'package:path/path.dart';
return openDatabase(
path,
await db.execute('''
name TEXT,
age INTEGER
''');
},
version: 1,
);
CopyEdit
Future<void> insertUser(String name, int age) async {
await db.insert(
'users',
conflictAlgorithm: ConflictAlgorithm.replace,
);
📌 Read Data
dart
CopyEdit
return db.query('users');
📌 Update Data
dart
CopyEdit
await db.update(
'users',
);
📌
Delete Data
dart
CopyEdit
await db.delete(
'users',
whereArgs: [id],
);
dart
CopyEdit
print(users);
}
📌 Best Practices:
1. Avoid opening the database multiple times. Open it once and reuse the instance.
2. Use DAOs (Data Access Objects) for better organization.
3. Consider using moor/drift package if you prefer an ORM-like approach.
Want me to show you how to refactor this code for better structure and scalability? 😊
You said:
Real-time database updates using Firebase, Authentication in Flutter
apps using Firebase Auth.
ChatGPT said:
✅ Setting Up Firebase
1.
2.
3.
4.
1. Follow the steps to register your app (Package name, App nickname, etc.).
2. Download the google-services.json (for Android) or GoogleService-
Info.plist (for iOS) and place them in your project directory:
1. Android: android/app/
2. iOS: ios/Runner/
5.
6.
yaml
CopyEdit
dependencies:
flutter:
sdk: flutter
firebase_core: ^2.16.0
firebase_auth: ^5.11.0
cloud_firestore: ^4.9.0
Run:
bash
CopyEdit
dart
CopyEdit
import 'package:flutter/material.dart';
import 'package:firebase_core/firebase_core.dart';
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp();
runApp(MyApp());
@override
Widget build(BuildContext context) {
return MaterialApp(
home: HomeScreen(),
);
CopyEdit
import 'package:firebase_auth/firebase_auth.dart';
try {
await FirebaseAuth.instance.createUserWithEmailAndPassword(
email: email,
password: password,
);
} catch (e) {
print(e.toString());
📌 Sign In User
dart
CopyEdit
Future<void> signIn(String email, String password) async {
try {
await FirebaseAuth.instance.signInWithEmailAndPassword(
email: email,
password: password,
);
} catch (e) {
print(e.toString());
CopyEdit
await FirebaseAuth.instance.signOut();
CopyEdit
User? getCurrentUser() {
return FirebaseAuth.instance.currentUser;
CopyEdit
import 'package:cloud_firestore/cloud_firestore.dart';
await FirebaseFirestore.instance.collection('users').doc(userId).set({
'name': name,
'age': age,
'createdAt': FieldValue.serverTimestamp(),
});
CopyEdit
return FirebaseFirestore.instance
.collection('users')
.snapshots()
📌 Updating Data
dart
CopyEdit
await
FirebaseFirestore.instance.collection('users').doc(userId).update({
'name': name,
});
}
📌 Deleting Data
dart
CopyEdit
await FirebaseFirestore.instance.collection('users').doc(userId).delete();
CopyEdit
import 'package:flutter/material.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
@override
return Scaffold(
stream: getUsers(),
if (snapshot.connectionState == ConnectionState.waiting) {
if (snapshot.hasError) {
}
final users = snapshot.data ?? [];
return ListView.builder(
itemCount: users.length,
return ListTile(
title: Text(user['name']),
);
},
);
},
),
);