2023年1月11日 星期三

Flutter學習-firebase Cloud Firestore說明(1)

 翻譯自:https://firebase.flutter.dev/docs/firestore/usage/

Cloud Firestore
注意

已存檔 FlutterFire firebase.google.com

使Cloud Firestore入下列程式

import 'package:cloud_firestore/cloud_firestore.dart';


使 Firestore FlutterFire Firestore宣告一個FirebaseFirestore的實例


FirebaseFirestore firestore = FirebaseFirestore.instance;


上面的作法可以讓你的裝置和Firestore進行連接。 但是,如果您想使用宣告一個次要的Firebase App的Firestore,請使用instanceFormethod:


FirebaseApp secondaryApp = Firebase.app('SecondaryApp');
FirebaseFirestore firestore = FirebaseFirestore.instanceFor(app: secondaryApp);


Collections & Documents#

Firestore "documents""collections"使使 使"collections"使"documents"


import 'package:flutter/material.dart';
// import入方法庫
import 'package:firebase_core/firebase_core.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
//創建一個增加使用者的類別方法
class AddUser extends StatelessWidget {
final String fullName;
final String company;
final int age;
AddUser(this.fullName, this.company, this.age);
Widget build(BuildContext context) {
// usersCollectionReferenceFirestoreusers

CollectionReference users = FirebaseFirestore.instance.collection('users');
//異步的增加一個使用者,所以用Future,不需要回傳值
Future<void> addUser() {
// 使CollectionReference使
return users
.add({
'full_name': fullName, // John Doe
'company': company, // Stokes and Sons
'age': age // 42
})
.then((value) => print("User Added"))
.catchError((error) => print("Failed to add user: $error"));
}
return TextButton(
onPressed: addUser,
child: Text(
"Add User",
),
);
}
}


Read Data

Cloud Firestore


One-time Read#(單次讀取)

調Query.getDocumentReference.get 使FutureBuilder


class GetUserName extends StatelessWidget {
final String documentId;
GetUserName(this.documentId);
Widget build(BuildContext context) {
CollectionReference users = FirebaseFirestore.instance.collection('users');
return FutureBuilder<DocumentSnapshot>(
future: users.doc(documentId).get(),
builder:
(BuildContext context, AsyncSnapshot<DocumentSnapshot> snapshot) {
if (snapshot.hasError) {
return Text("Something went wrong");
}
if (snapshot.hasData && !snapshot.data!.exists) {
return Text("Document does not exist");
}
if (snapshot.connectionState == ConnectionState.done) {
Map<String, dynamic> data = snapshot.data!.data() as Map<String, dynamic>;
return Text("Full Name: ${data['full_name']} ${data['last_name']}");
}
return Text("loading");
},
);
}
}


多關


Realtime changes#(即時,持續性的讀取)

FlutterFire/ CollectionReferenceDocumentReferencesnapshotsStream


Stream collectionStream = FirebaseFirestore.instance.collection('users').snapshots();
Stream documentStream = FirebaseFirestore.instance.collection('users').doc('ABC123').snapshots();


通過listen()使StreamBuilder你管理傳入資料的狀態,並在應用程序中不再使用流時自動結束資料讀取:


class UserInformation extends StatefulWidget {
_UserInformationState createState() => _UserInformationState();
}
class _UserInformationState extends State<UserInformation> {
final Stream<QuerySnapshot> _usersStream = FirebaseFirestore.instance.collection('users').snapshots();
Widget build(BuildContext context) {
//以下為使用StreamBuilder讀取資料的方法
return StreamBuilder<QuerySnapshot>(
//要讀取的方法,已在前調用
stream: _usersStream,
builder: (BuildContext context, AsyncSnapshot<QuerySnapshot> snapshot) {
if (snapshot.hasError) {
return Text('Something went wrong');
}
if (snapshot.connectionState == ConnectionState.waiting) {
return Text("Loading");
}
return ListView(
children: snapshot.data!.docs.map((DocumentSnapshot document) {
Map<String, dynamic> data = document.data()! as Map<String, dynamic>;
return ListTile(
title: Text(data['full_name']),
subtitle: Text(data['company']),
);
}).toList(),
);
},
);
}
}


自身的資料,監聽就不會更新。如果您想要在文件或查詢自身的資料更改時接收事件,您可以將includeMetadataChanges傳遞給snapshots方法:


FirebaseFirestore.instance
.collection('users')
.snapshots(includeMetadataChanges: true)


Document & Query Snapshots#

FirestoreQuerySnapshotDocumentSnapshot

QuerySnapshot

QuerySnapshotQuerySnapshotdocsDocumentSnapshot


FirebaseFirestore.instance
.collection('users')
.get()
.then((QuerySnapshot querySnapshot) {
querySnapshot.docs.forEach((doc) {
print(doc["first_name"]);
});
});


DocumentSnapshot DocumentSnapshot使使exists


FirebaseFirestore.instance
.collection('users')
.doc(userId)
.get()
.then((DocumentSnapshot documentSnapshot) {
if (documentSnapshot.exists) {
print('Document exists on the database');
}
});


調dataMap<String, dynamic>null


FirebaseFirestore.instance
.collection('users')
.doc(userId)
.get()
.then((DocumentSnapshot documentSnapshot) {
if (documentSnapshot.exists) {
print('Document data: ${documentSnapshot.data()}');
} else {
print('Document does not exist on the database');
}
});


DocumentSnapshot通過getMapFieldPathStateError


try {
dynamic nested = snapshot.get(FieldPath(['address', 'postcode']));
} on StateError catch(e) {
print('No nested field exists!');
}


Querying#(查詢)

Cloud Firestore # whereequality checks和“in”查詢。例如,篩選其年齡大於20歲的用戶:


FirebaseFirestore.instance
.collection('users')
.where('age', isGreaterThan: 20)
.get()
.then(...);


Firestoreenit使使arrayContainsAny


FirebaseFirestore.instance
.collection('users')
.where('language', arrayContainsAny: ['en', 'it'])
.get()
.then(...);


Cloud Firestore Firebase 制查件數使 limit


FirebaseFirestore.instance
.collection('users')
.limit(2)
.get()
.then(...);


使 limitToLast


FirebaseFirestore.instance
.collection('users')
.orderBy('age')
.limitToLast(2)
.get()
.then(...);


Ordering#(排序)

使 orderBy


FirebaseFirestore.instance
.collection('users')
.orderBy('age', descending: true)
.get()
.then(...);


Start & End Cursors#

定點/startAtendAtstartAfterendBefore使

FirebaseFirestore.instance
.collection('users')
.orderBy('age')
.orderBy('company')
.startAt([4, 'Alphabet Inc.'])
.endAt([21, 'Google LLC'])
.get()
.then(...);

DocumentSnapshot startAfterDocumentstartAtDocumentendAtDocument endBeforeDocument變更指定查詢的結果。例如:

FirebaseFirestore.instance
.collection('users')
.orderBy('age')
.startAfterDocument(documentSnapshot)
.get()
.then(...);

Query Limitations#

Cloud Firestore OR OR != where("age", isNotEqualTo: 30)通過 where("age", isLessThan: 30) where("age", isGreaterThan: 30)

沒有留言:

張貼留言