1.はじめに
新たに6つのAndroidStudio&Flutter&Firebase記事を書いている。以下は内容、
- 【Flutter/Dart】Firebaseを使おう
https://qiita.com/my_programming/private/7b3251701183ff59b97c - 【Flutter/Dart】Firebase Authenticationを使って認証アプリを作ろう
https://qiita.com/my_programming/private/2d81229942bc0d61da6b - 【Flutter/Dart】Firebase/Firestoreを使ったチャットアプリを作ろう
- 【Flutter/Dart】Firebase/Firestoreを使ったToDoアプリを作ろう
https://qiita.com/my_programming/private/2da77f3a36bf120761c5 - 【Flutter/Dart】Firebase/HostingでWebアプリを外部公開しよう
https://qiita.com/my_programming/private/5950b7e27161dc9ec838 - 【Flutter/Dart】Firebase/Firestoreを使ったBlogアプリを作ろう
https://qiita.com/my_programming/private/6f8515dca825e55d0f07
今回はバックエンドにFirebaseを搭載したFlutterでわかりやすく複雑なチャットアプリケーションを作成する。
2. チャットアプリを作ろう
Firebaseのプロジェクトについては認証アプリで作成した。同じプロジェクトのページを開き、Cloud Firestoreを選択する。
AndroidStudioにて、チャットアプリを作るための新規プロジェクトを作成する。
以下は認証アプリと同様に、classpathをandroid/build.gradleの中にコピーする。
以下は認証アプリと同様に、android/app/build.gradle
にidをペーストしてapply plugin: 'com.google.gms.google-services'
の通りに書き換える。
以下は認証アプリと同様に、dependenciesの中のimplementationの2行をコピーしてandroid/app/build.gradleにペーストする。
以下は認証アプリと同様に、2つのパッケージをdart package
で検索、コピーしたバージョン情報をpubspec.yamlにペースト、右上のPub getを押す。
applicationId
が"com.example.my_chat_app"になっていることを確認する。
以下は認証アプリと同様に、android/app/build.gradle
のminSdkVersionを23に、targetSdkVersionを30に変更する。applicationId
を"com.example.my_auth_app"に書き換える。これで、認証アプリと同じFirebaseプロジェクトのデータベースを利用できる様になる。
lib/main.dartにチャット用のコードを記述。
import 'package:flutter/material.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp();
runApp(new MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new MaterialApp(
title: 'Chat App',
theme: new ThemeData(
primaryColor: Colors.red
),
home: new UserPage(),
);
}
}
class UserPage extends StatefulWidget {
@override
_UserPageState createState() => new _UserPageState();
}
class _UserPageState extends State<UserPage> {
final _controller = TextEditingController();
@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text("User Name Input Screen"),
backgroundColor: Colors.red
),
body: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Container(
margin: EdgeInsets.all(12.0),
child: TextFormField(
controller: _controller,
decoration: InputDecoration(
labelText: 'User Name'
),
),
),
ElevatedButton(
onPressed: () {
Navigator.push(
context, MaterialPageRoute(builder: (builder) => ChatPage(_controller.text)));
},
child: Text("Setup complete", style: TextStyle(color: Colors.white),),
)
],
),
);
}
}
class ChatPage extends StatefulWidget {
ChatPage(this._userName);
final String _userName;
@override
_ChatPageState createState() => new _ChatPageState();
}
class _ChatPageState extends State<ChatPage> {
final _controller = TextEditingController();
@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text("chat page"),
backgroundColor: Colors.red
),
body: Container(
margin: const EdgeInsets.symmetric(horizontal: 10.0),
child: Column(
children: <Widget>[
Flexible(
child: StreamBuilder<QuerySnapshot>(
stream: FirebaseFirestore.instance
.collection("ChatApp")
.orderBy("time", descending: true)
.snapshots(),
builder: (context, snapshot) {
if (!snapshot.hasData) return Container();
return new ListView.builder(
padding: new EdgeInsets.all(8.0),
reverse: true,
itemBuilder: (_, int index) {
DocumentSnapshot document =
snapshot.data!.docs[index];
bool isSelfText = false;
if (document['username'] == widget._userName) {
isSelfText = true;
}
return isSelfText
? _SelfText(
document['sent_text'], document['username'])
: _OtherText(
document['sent_text'], document['username']);
},
itemCount: snapshot.data!.docs.length,
);
},
),
),
new Divider(height: 1.0),
Container(
margin: EdgeInsets.only(bottom: 20.0, right: 10.0, left: 10.0),
child: Row(
children: <Widget>[
new Flexible(
child: new TextField(
controller: _controller,
onSubmitted: _handleSubmit,
decoration:
new InputDecoration.collapsed(hintText: "send text"),
),
),
new Container(
child: new IconButton(
icon: new Icon(
Icons.chat,
color: Colors.red,
),
onPressed: () {
_handleSubmit(_controller.text);
}),
),
],
),
),
],
),
));
}
Widget _SelfText(String message, String userName) {
return Row(
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[
Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
SizedBox(height: 12.0,),
Text(userName, style: TextStyle(color: Colors.red)),
Text(message),
],
),
Icon(Icons.person, color:Colors.red),
],
);
}
Widget _OtherText(String message, String userName) {
return Row(
children: <Widget>[
Icon(Icons.person_outline),
Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
SizedBox(height: 12.0,),
Text(userName),
Text(message),
],
)
],
);
}
_handleSubmit(String message) {
_controller.text = "";
var db = FirebaseFirestore.instance;
db.collection("ChatApp").add({
"username": widget._userName,
"sent_text": message,
"time": DateTime.now()
}).then((val) {
print("Success");
}).catchError((err) {
print(err);
});
}
}
次に前の画面に戻ってユーザー2の名前を入力し、ユーザー2のテキストを投稿する。
ユーザー2名分のテキストが、Cloud Firestoreのデータベースに反映されていることが確認できる。
以上で、FlutterとFirebaseを用いたチャットアプリが完成した。
3.まとめ
FlutterとFirebaseを用いたチャットアプリの作成方法を学んだ。