Snehil Gupta Project Report
Snehil Gupta Project Report
Kanpur, U.P.
MASTER OF COMPUTER
APPLICATION
Flutter Development
Submitted to:- Submitted by:-
Dr. Imran khan Snehil Gupta
Dr Amit Gupta MCA (3rd sem)
Parul pandey 210231071
Pooja agnihotri
_CERTIFICATE_
_Acknowledgement_
I offer sincere thanks and humble regards to Piety Innovation Labs, based in
Singapore, for imparting me very valuable professional training in MCA.
I take the opportunity to express gratitude and thanks to our computer labs staff
for providing me opportunity to utilize the available resources for the
completion of the project.
Snehil Gupta
[ 210231071 ]
INDEX
S.N. TOPIC
I Cover Page
II Certificate
III Acknowledgement
IV Index
1 Introduction
What is Flutter
What is Dart
Flutter Architecture
Why did I choose Flutter
Why Firebase
3 The Files(modules)
home_page.dart
sign_up.dart
login.dart
chat_screen.dart
4 Demonstration
6 Bibliography
7 Conclusion
Introduction
What is Flutter !
Flutter is a free and open-source UI framework for creating native mobile
applications from Google. Released in 2017, Flutter allows developers to build
mobile applications with a single codebase and programming language. This
capability makes building both iOS and Android apps simpler and faster.
The Flutter framework consists of both a software development kit (SDK) and
their widget-based UI library. This library consists of various reusable UI
elements, such as sliders, buttons, and text inputs.
What is Dart
Dart is a high-level, interpreted programming language that lets you build
mobile, server, desktop and web applications. Some people even consider it to
be an alternative solution to Javascript. Though the first version of Dart was
available by mid-autumn, its popularity grew when Flutter (ideal choice for
many for cross-platform development) was released in 2017.
A major difference that Dart has from other programming languages is that it
comes with its own package manager known as Pub; developers can use these
packages to build Dart and Flutter apps.
Benefits
Easy to learn language
Comes with good Documentation
High performance factor
Dart’s syntax is clean
Excellent tooling support
Can compile to self-contained snapshots
Can write the first program without installation or configuration
A good support for the programmer
More type-safe than Javascript
Dart is portable
Flutter Architecture
Flutter is comprised of three architectural layers. Here is a quick breakdown of
each one:
Some of the top reasons why development teams choose Flutter include:
Increased productivity. Using the same codebase for iOS and Android
saves both time and resources. Flutter’s native widgets also minimize
time spent on testing by ensuring there is little to no compatibility issues
with different OS versions.
Easy to learn. Flutter allows developers to build native mobile
applications without needing to access OEM widgets or use a lot of code.
This, in addition to Flutter’s particularly appealing user interface, makes
the mobile app creation process much simpler.
Great performance. Users report that it is difficult to notice the
difference between a Flutter app and a native mobile app.
Cost-effective. Building iOS and Android apps with the same codebase is
essentially building two apps for the price of one.
Available on different IDEs. Developers are free to choose between
Android Studio and VS Code to edit their code on Flutter.
Application rendering. This unique feature allows Flutter to draw and
display its own UI components. By not relying on UI components from
the target system, Flutter offers an unparalleled level of detail, runtime
performance, and control when compared to other frameworks.
Great documentation & community. Flutter has many great resources
to answer your questions, thanks to its ample documentation with easy-
to-follow use cases. Flutter users also benefit from community hubs
like Flutter Community and Flutter Awesome for exchanging ideas.
Flutter App Development Pros
Flutter offers a wide range of benefits for business folks and developers alike.
Flutter offers good quality for reasonable costs, as well as great usability and
speed.
Development goes faster when the same code is used for both iOS and
Android applications. Flutter’s singular codebase speeds up time-to-
market while cutting mobile app development costs significantly.
There are many start-up companies using Flutter, but above I have listed some
of the most popular names.
Why Firebase ?
Now, if we were to define the BaaS, it is a cloud computing service model using
which the web app and mobile app developers can connect their applications
with backend cloud storage and APIs rendered by the backend applications.
In addition, it also helps you to develop storage for the app including
authentication functionality.
Moreover, Firebase can also be used effectively for app marketing, enhancing
the user experience and user engagement.
Firebase Authentication
1) Installing plugins
These plugins help login app by Google account, get user info, real-time
database for chatting and upload image.
firebase_auth
google_sign_in
cloud_firestore
firebase_storage
And the others will help us show toast, cache data local, pick images from
gallery, cache network image and parse date time.
fluttertoast
shared_preferences
image_picker
cached_network_image
intl
2. The Files
Basically I tried to keep the code clean and manageable so I used four basic
screen to keep abstraction upto the mark.
home_page.dart
@override
State<HomePage> createState() => _HomePageState();
}
@override
Widget build(BuildContext context) {
// print(FirebaseAuth.instance.currentUser!.uid);
return Scaffold(
appBar: AppBar(
title: Text("Users"),
automaticallyImplyLeading: false,
centerTitle: true,
actions: <Widget>[
TextButton(
style: ButtonStyle(
foregroundColor:
MaterialStateProperty.all(Colors.white),
shape:MaterialStateProperty.all<RoundedRectangleBorde
r>(
RoundedRectangleBorder(
borderRadius:
BorderRadius.circular(18.0),
side: BorderSide(color:
Colors.red)
),
),
),
onPressed: () async {
await FirebaseAuth.instance.signOut();
},
child: Text("Signout"),
),
],
),
body: StreamBuilder(
stream: FirebaseFirestore.instance
.collection("users")
.where('uid',
isNotEqualTo:
FirebaseAuth.instance.currentUser!.uid)
.snapshots(),
builder: ((context,
AsyncSnapshot<QuerySnapshot<Map<String,
dynamic>>> snapshot) {
if (snapshot.connectionState ==
ConnectionState.waiting) {
return const Center(
child: CircularProgressIndicator(),
);
}
if (!snapshot.hasData) {
return const Center(
child: CircularProgressIndicator(),
);
}
return ListView.builder(
itemCount: snapshot.data!.docs.length,
itemBuilder: (context, index) {
UserModel user =
UserModel.fromJson(snapshot.data!.docs[index]);
return InkWell(
autofocus: true,
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) =>
Chat_Screen(uid: user.uid),
));
},
child: ListTile(
title: Text(user.userName),
subtitle: Text(user.userEmail),
),
);
},
);
})),
);
}
}
sign_up.dart
@override
State<SignUp> createState() => _SignUpState();
}
@override
Widget build(BuildContext context) {
final authProvider =
Provider.of<AuthProvider>(context);
print(authProvider.isLoading);
return Padding(
padding: const EdgeInsets.all(10),
child: Scaffold(
body: ListView(
children: <Widget>[
Container(
alignment: Alignment.center,
padding: const EdgeInsets.all(10),
child: const Text(
'ChatApp',
style: TextStyle(
color: Colors.blue,
fontWeight: FontWeight.w500,
fontSize: 30),
)),
Container(
alignment: Alignment.center,
padding: const EdgeInsets.all(10),
child: const Text(
'Sign up',
style: TextStyle(fontSize: 20),
)),
authProvider.errormsg.isNotEmpty
? Padding(
padding: const
EdgeInsets.all(8.0),
child: Text(
authProvider.errormsg,
style: TextStyle(
color: Colors.red,
),
),
)
: Container(),
Container(
padding: const EdgeInsets.all(10),
child: TextField(
controller: emailController,
decoration: const InputDecoration(
border: OutlineInputBorder(),
labelText: 'Email',
),
),
),
Container(
padding: const EdgeInsets.all(10),
child: TextField(
controller: nameController,
decoration: const InputDecoration(
border: OutlineInputBorder(),
labelText: 'User Name',
),
),
),
Container(
padding: const
EdgeInsets.fromLTRB(10, 10, 10, 0),
child: TextField(
obscureText: true,
controller: passwordController,
decoration: const InputDecoration(
border: OutlineInputBorder(),
labelText: 'Password',
),
),
),
SizedBox(
height: 20,
),
Container(
height: 50,
padding: const
EdgeInsets.fromLTRB(10, 0, 10, 0),
child: ElevatedButton(
child: authProvider.isLoading ==
true
? Center(
child:
CircularProgressIndicator(
color: Colors.white,
),
)
: Text('Signup'),
onPressed: () async{
await
authProvider.setSignUp(nameController.text,
emailController.text,
passwordController.text);
if
(authProvider.errormsg.isEmpty ||
authProvider.errormsg==null) {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) =>
HomePage(),
));
}
},
)),
Row(
children: <Widget>[
const Text('Already have an
account?'),
TextButton(
child: Text(
'Sign in',
style: TextStyle(fontSize: 20),
),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) =>
LoginScreen(),
));
},
)
],
mainAxisAlignment:
MainAxisAlignment.center,
),
],
),
));
}
}
login.dart
@override
State<LoginScreen> createState() =>
_LoginScreenState();
}
@override
Widget build(BuildContext context) {
final authProvider =
Provider.of<AuthProvider>(context);
return Padding(
padding: const EdgeInsets.all(10),
child: Scaffold(
body: ListView(
children: <Widget>[
Container(
alignment: Alignment.center,
padding: const EdgeInsets.all(10),
child: const Text(
'ChatApp',
style: TextStyle(
color: Colors.blue,
fontWeight: FontWeight.w500,
fontSize: 30),
)),
Container(
alignment: Alignment.center,
padding: const EdgeInsets.all(10),
child: const Text(
'Sign in',
style: TextStyle(fontSize: 20),
)),
authProvider.errormsg.isNotEmpty
? Text(
authProvider.errormsg,
style: TextStyle(color:
Colors.red),
)
: Container(),
Container(
padding: const EdgeInsets.all(10),
child: TextField(
controller: emailController,
decoration: const InputDecoration(
border: OutlineInputBorder(),
labelText: 'Email',
),
),
),
Container(
padding: const
EdgeInsets.fromLTRB(10, 10, 10, 0),
child: TextField(
obscureText: true,
controller: passwordController,
decoration: const InputDecoration(
border: OutlineInputBorder(),
labelText: 'Password',
),
),
),
SizedBox(
height: 20,
),
Container(
height: 50,
padding: const
EdgeInsets.fromLTRB(10, 0, 10, 0),
child: ElevatedButton(
child: authProvider.isLoading
? Center(
child:
CircularProgressIndicator(
color: Colors.white,
),
)
: Text('Login'),
onPressed: () {
authProvider.setSignIn(
emailController.text,
passwordController.text);
if
(authProvider.errormsg.isEmpty) {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) =>
HomePage(),
));
}
},
)),
Row(
children: <Widget>[
const Text('Does not have
account?'),
TextButton(
child: const Text(
'Sign Up',
style: TextStyle(fontSize: 20),
),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) =>
SignUp(),
));
},
)
],
mainAxisAlignment:
MainAxisAlignment.center,
),
],
),
));
}
}
chat_screen.dart
@override
State<Chat_Screen> createState() =>
_Chat_ScreenState();
}
generateGroupId() {
currentUserId =
FirebaseAuth.instance.currentUser!.uid;
peerId = widget.uid;
if (currentUserId.compareTo(peerId) > 0) {
groupChatId = '$currentUserId-$peerId';
} else {
groupChatId = '$peerId-$currentUserId';
}
updateDataFirestore(
FirestoreConstants.pathUserCollection,
currentUserId,
{FirestoreConstants.chattingWith: peerId},
);
}
Future<void> updateDataFirestore(String
collectionPath, String docPath,
Map<String, dynamic> dataNeedUpdate) {
return FirebaseFirestore.instance
.collection(collectionPath)
.doc(docPath)
.update(dataNeedUpdate);
}
sendChat({required String messaage}) async {
MessageChat chat = MessageChat(
content: messaage,
idFrom: currentUserId,
idTo: peerId,
timestamp: Timestamp.now().toString());
await FirebaseFirestore.instance
.collection("groupMessages")
.doc(groupChatId)
.collection("messages")
.add(chat.toJson());
_messageController.text = "";
//
}
@override
void initState() {
generateGroupId();
_scrollDown();
super.initState();
}
@override
void dispose() {
_messageController.dispose();
super.dispose();
}
void _scrollDown() {
if (_controller.hasClients) {
_controller.jumpTo(_controller.position.maxScrollExte
nt);
}
}
Future<bool> onBackPress() {
updateDataFirestore(
FirestoreConstants.pathUserCollection,
currentUserId,
{FirestoreConstants.chattingWith: null},
);
Navigator.pop(context);
return Future.value(false);
}
@override
Widget build(BuildContext context) {
return WillPopScope(
onWillPop: onBackPress,
child: Scaffold(
appBar: AppBar(
automaticallyImplyLeading: false,
leading: IconButton(
icon: Icon(Icons.arrow_back_ios),
onPressed: () {
onBackPress();
}),
title: const Text("Your Chats"),
centerTitle: true,
),
bottomNavigationBar: SafeArea(
child: Container(
margin: EdgeInsets.only(
bottom:
MediaQuery.of(context).viewInsets.bottom),
height: 60,
width: media(context).width,
child: Row(
crossAxisAlignment:
CrossAxisAlignment.center,
mainAxisAlignment:
MainAxisAlignment.center,
children: [
IconButton(
onPressed: () {
// pickImage();
},
icon: Icon(Icons.image)),
IconButton(onPressed: () {}, icon:
Icon(Icons.person)),
Container(
width: media(context).width / 2,
child: TextField(
decoration:
InputDecoration(label: Text("Enter message")),
controller: _messageController,
),
),
IconButton(
onPressed: () {
sendChat(messaage:
_messageController.text);
_messageController.text = "";
_scrollDown();
FocusManager.instance.primaryFocus?.unfocus();
},
icon: Icon(Icons.send))
],
),
),
),
body: StreamBuilder(
stream: FirebaseFirestore.instance
.collection("groupMessages")
.doc(groupChatId)
.collection("messages")
.orderBy(FirestoreConstants.timestamp, descending:
true)
.snapshots(),
builder: (context,
AsyncSnapshot<QuerySnapshot<Map<String, dynamic>>>
snapshot) {
if (snapshot.connectionState ==
ConnectionState.waiting) {
return const Center(
child: CircularProgressIndicator(),
);
}
return ListView.builder(
reverse: true,
shrinkWrap: true,
controller: _controller,
itemCount:
snapshot.data!.docs.length,
itemBuilder: (context, index) {
MessageChat chat =
MessageChat.fromDocument(snapshot.data!.docs[index]);
return ChatBubble(
text: chat.content,
isCurrentUser:
chat.idFrom ==
currentUserId ? true : false);
},
);
}),
),
);
}
}
Demonstration
For this I made two accounts:-
And passed messages side by side in real time. You can see the
separate screens above and below.
Bibliography
pub.dev
https://api.flutter.dev/index.html
https://docs.flutter.dev/development/ui/widgets
Medium.com
You tube tutorials
Conclusion
The project "Chatting App(with flutter)" which was assigned to me to help
understand various real life problems which you have to go through to
develop any project.
During this period i Leamed basics of Dart and State Management and also
applied it to my projects. Alot of new learnings which I got through this
includes Learning new technologies within a limited time.
Organizing a large code base, Making responsive app so that it works for
nearly all mobile phones as well as Desktop & Web.
New task was assigned before completion of previous one, Worked on real
life projects in the organization.