firestoreのセキュリティルール
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
match /{document=**} {
allow read, write: if request.time < timestamp.date(2023, 10, 3);
}
}
}
認証されたユーザのみ許可に変更
match /{document=**} {
allow read, write: if request.auth != null && request.auth.uid != null;
}
### Authenticationによるユーザ認証
FirebaseのauthenticationでGoogleを許可する
$ flutter pub add firebase_auth
$ flutter pub upgrade firebase_auth
$ flutter pub add google_sign_in
$ flutter pub upgrade google_sign_in
import 'package:flutter/material.dart';
import 'dart:ui' as ui;
import 'dart:convert';
import 'dart:io';
import 'package:firebase_core/firebase_core.dart';
import 'firebase_options.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:google_sign_in/google_sign_in.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp(
options: DefaultFirebaseOptions.currentPlatform,
);
runApp(new MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new MaterialApp(
title: 'Generated App',
theme: new ThemeData(
primarySwatch: Colors.blue,
primaryColor: const Color(0xFF2196f3),
canvasColor: const Color(0xFFfafafa),
),
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key? key}) : super(key: key);
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
final _controller = TextEditingController();
static const url = 'https://jsonplaceholder.typicode.com/posts';
@override
void initState(){
super.initState();
fire();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Home'),
),
body: Padding(
padding: EdgeInsets.all(20.0),
child:Column(
children:<Widget> [
Text('INTERNET ACCESS',
style: TextStyle(fontSize: 32,
fontWeight: ui.FontWeight.w500),
),
Padding(padding: EdgeInsets.all(10.0)),
TextField(
controller: _controller,
style: TextStyle(fontSize: 24),
minLines: 1,
maxLines: 5,
),
],
),
),
floatingActionButton: FloatingActionButton(
child: Icon(Icons.open_in_new),
onPressed: () {
doSignin();
}
)
);
}
void addDoc() async {
var msg = _controller.text;
final input = msg.split(',');
final data = {
'name': input[0],
'mail': input[1],
'age': input[2]
};
FirebaseFirestore firestore = FirebaseFirestore.instance;
final snapshot = await firestore.collection('mydata')
.add(data);
fire();
}
void fire() async {
var msg = '';
FirebaseFirestore firestore = FirebaseFirestore.instance;
final snapshot = await firestore.collection('mydata')
.orderBy('name', descending: false).get();
snapshot.docChanges.forEach((element) {
final name = element.doc.get('name');
final mail = element.doc.get('mail');
final age = element.doc.get('age');
msg += "\n${name} (${age}) <${mail}>";
});
_controller.text = msg;
}
Future<UserCredential> signInWithGoogle() async {
final GoogleSignInAccount? googleUser = await GoogleSignIn().signIn();
final GoogleSignInAuthentication? googleAuth = await googleUser?.authentication;
final credential = GoogleAuthProvider.credential(
accessToken: googleAuth?.accessToken,
idToken: googleAuth?.idToken,
);
return await FirebaseAuth.instance.signInWithCredential(credential);
}
void doSignin() {
signInWithGoogle().then((value) {
if(value.user != null) {
fire();
}
});
}
}