Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Flutter X Firestore

Flutter X Firestore

Introduction to Firestore in Flutter with some tips!

Avatar for Miguel Beltran

Miguel Beltran

July 15, 2019
Tweet

More Decks by Miguel Beltran

Other Decks in Technology

Transcript

  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. 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. What is Firestore “flexible, scalable NoSQL cloud database to store

    and sync data for client- and server-side development”
  4. Paths /users /channels Collection of Users Collection of Channels /users/miguel

    /channels/general Document ‘miguel’ Document ‘general’
  5. 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. 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. Reading documents // Future<DocumentSnapshot> document = await firestore.document(path).get() // Can

    be Server, Cache or both get({Source source = Source.serverAndCache})
  8. Reading documents // Future<DocumentSnapshot> document = await firestore.document(path).get() // read

    the field ‘rating’ rating = document[‘rating’] // check if document exists if (!document.exists) { … }
  9. 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
  10. Organising paths class FirestorePaths { static String pathGifs = '/gifs';

    static String pathRatings = '/ratings'; static String getPathRating(String id, String user) { return "$pathGifs/$id$pathRatings/$user"; } }
  11. 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()
  12. 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
  13. Reliable data // avoid using int or double double.parse(doc[‘rating']) //

    safe parsing double.tryParse(doc['rating']) ?? 0.0
  14. Defensive Programming Practice defensive programming Recover from database errors Examples:

    - Filter bad data - Parse with tryParse methods - Default values
  15. 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) })
  16. Redux Middleware List<Middleware<AppState>> createMiddleware( GifRepository gifRepository, ) { return [

    TypedMiddleware<AppState, LoadGifsAction>(_loadGifs(gifRepository)), ]; }
  17. 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)); }; }
  18. 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; }
  19. Streams in Redux // in my GifReview Widget @override void

    dispose() { super.dispose(); store.dispatch(UnsubscribeAction()); } // in the Middleware, on UnsubscribeAction store.state.subscription.cancel();
  20. • 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
  21. 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