Flutter X Firestore

Flutter X Firestore

Introduction to Firestore in Flutter with some tips!

72ffb135de71bef2c4a11961634edc6a?s=128

Miguel Beltran

July 15, 2019
Tweet

Transcript

  1. 1.

    Flutter ╳ Firestore M i g u e l B

    e l t r a n @ M i B LT b e l t r a n . w o r k
  2. 2.

    Why this talk • Because Firestore is cool • Building

    (a real) project with Flutter and Firestore • No documentation on how to use Firestore with Flutter • Share my tips and tricks
  3. 4.

    What is Firestore “flexible, scalable NoSQL cloud database to store

    and sync data for client- and server-side development”
  4. 6.

    Paths /users /channels Collection of Users Collection of Channels /users/miguel

    /channels/general Document ‘miguel’ Document ‘general’
  5. 7.

    Subcollections /channels Collection of Channels /channels/general/messages Subcollection of Messages Messages

    “hello!” “I have a q…” Channels “general” “random” “jobs” Messages “I am hiring” “New job”
  6. 10.

    Access data Read once a single document Read once a

    collection of documents Read updates from a single document Read updates from a collection
  7. 14.
  8. 15.
  9. 16.
  10. 21.

    Reading documents // Future<DocumentSnapshot> document = await firestore.document(path).get() // Can

    be Server, Cache or both get({Source source = Source.serverAndCache})
  11. 22.

    Reading documents // Future<DocumentSnapshot> document = await firestore.document(path).get() // read

    the field ‘rating’ rating = document[‘rating’] // check if document exists if (!document.exists) { … }
  12. 24.

    Example: Read rating of a gif path = FirestorePaths.getPathRating(id, user)

    document = await firestore.document(path).get() if (!document.exists) { return 0.0 } return double.tryParse(document['rating']) ?? 0.0
  13. 28.

    Organising paths class FirestorePaths { static String pathGifs = '/gifs';

    static String pathRatings = '/ratings'; static String getPathRating(String id, String user) { return "$pathGifs/$id$pathRatings/$user"; } }
  14. 33.

    Reading documents & collections Read document with document(path).get() Write document

    with document(path).setData({data}) collection(path).add({data}) Read a collection with collection(path).getDocuments()
  15. 41.

    Organize Firestore files Use Repositories gif_repository.dart rating_repository.dart Do not call

    to Firestore from your Middleware/BLOC/etc. • Testing Firestore is hard • You want this to be easy to replace
  16. 42.

    Reliable data // avoid using int or double double.parse(doc[‘rating']) //

    safe parsing double.tryParse(doc['rating']) ?? 0.0
  17. 43.

    Defensive Programming Practice defensive programming Recover from database errors Examples:

    - Filter bad data - Parse with tryParse methods - Default values
  18. 44.
  19. 45.

    Test “map” methods class MockDocumentSnapshot extends Mock implements DocumentSnapshot {}

    test("should map DocumentSnapshot to Gif", () { final document = MockDocumentSnapshot() when(document["url"]).thenReturn("URL") when(document.documentID).thenReturn(“ID") final outGif = GifRepository.fromDoc(document) expect(outGif, myGif) })
  20. 50.

    Redux Middleware List<Middleware<AppState>> createMiddleware( GifRepository gifRepository, ) { return [

    TypedMiddleware<AppState, LoadGifsAction>(_loadGifs(gifRepository)), ]; }
  21. 51.

    Redux Middleware void Function( Store<AppState> store, LoadGifsAction action, NextDispatcher next,

    ) _loadGifs(GifRepository gifRepository) { return (store, action, next) async { next(action); final gifs = await gifRepository.getGifs(); store.dispatch(OnLoadedGifsAction(gifs)); }; }
  22. 53.

    Streams in Redux // In Middleware subscription = ratingRepo.getRatings(id).listen((data) {

    store.dispatch(OnUpdatedRatingsAction(data)); }); store.dispatch(OnSubscribedToRatingsAction(subscription)) Class AppState { // Keep the current subscription in the AppState StreamSubscription subscription; }
  23. 54.

    Streams in Redux // in my GifReview Widget @override void

    dispose() { super.dispose(); store.dispatch(UnsubscribeAction()); } // in the Middleware, on UnsubscribeAction store.state.subscription.cancel();
  24. 58.

    • Documents & collections • Paths • Read data once

    as Future • Read data continuously as Stream • Set data into document • Organize Firestore code into repositories • Unit test map methods & mock repositories • When using Redux, mind Streams
  25. 59.

    59 M i g u e l B e l

    t r a n F r e e l a n c e S o f t w a r e D e v e l o p e r C o n s u l t a n t Thank You! @ M i B LT b e l t r a n . w o r k