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

[Jana Moudrá] How AngularDart & Firebase did an...

[Jana Moudrá] How AngularDart & Firebase did an App together

Presentation from GDG DevFest Ukraine 2017 - the biggest community-driven Google tech conference in the CEE.

Learn more at: https://devfest.gdg.org.ua

Google Developers Group Lviv

October 13, 2017
Tweet

More Decks by Google Developers Group Lviv

Other Decks in Technology

Transcript

  1. <!DOCTYPE html> <html> <head> <title>AngularDart + FB = ♥ demo</title>

    <meta charset="utf-8"> <script src="firebase.js"></script> ... imports for Dart scripts and others </head> <body> <my-app>Loading...</my-app> </body> </html> index.html
  2. -> index.html <!DOCTYPE html> <html> <head> <title>AngularDart + FB =

    ♥ demo</title> <meta charset="utf-8"> <script src="firebase.js"></script> ... imports for Dart scripts and others </head> <body> <my-app>Loading...</my-app> </body> </html>
  3. @Component( selector: 'notes', templateUrl: 'notes_component.html', directives: const [CORE_DIRECTIVES]) class NotesComponent

    { List<Note> notes = []; // We need to retrieve notes somehow } notes_component.dart
  4. notes_component.dart -> @Component( selector: 'notes', templateUrl: 'notes_component.html', directives: const [CORE_DIRECTIVES])

    class NotesComponent { List<Note> notes = []; // We need to retrieve notes somehow }
  5. <div id="notes"> <div *ngFor="let note of notes"> <h3 *ngIf="note.title?.isNotEmpty"> {{note.title}}

    </h3> <div> <p>{{note.text}}</p> ... </div> ... </div> </div> notes_component.html
  6. Sign in with Google Read from realtime database Save to

    realtime database Upload to storage
  7. import 'package:firebase/firebase.dart'; ... var provider = new GoogleAuthProvider(); try {

    await auth().signInWithPopup(provider); } catch (e) { print('Error in sign in with Google: $e'); } signInAnonymously() signInWithEmailAndPassword(email, pass) ...
  8. Structure the data { "notes" : { "-KUsbAq6445-ynO4lg6Z" : {

    "img_url" : "dart.png", "text" : "Is awesome!", "title" : "Dart" }, ... } }
  9. List<Note> notes = []; DatabaseReference dbRef = database().ref("notes"); dbRef.onChildAdded.listen((e) {

    DataSnapshot data = e.snapshot; var val = data.val(); Note note = new Note(val["text"], ...); notes.insert(0, note); }); onValue onChildRemoved onChildMoved onChildChanged
  10. DatabaseReference dbRef = database().ref("notes"); try { await dbRef .push({"text": "New

    note!!!"}) .future; } catch (e) { print("Error in writing to database: $e"); }
  11. StorageReference stRef = storage().ref("notes"); File file = ...; try {

    UploadTaskSnapshot snapshot = await stRef .child(file.name) .put(file) .future; // Get url in snapshot.downloadURL } catch (e) { print("Error in uploading to storage: $e"); }
  12. import 'package:angular/angular.dart'; import 'package:firebase/firebase.dart'; ... @Injectable() class FirebaseService { List<Note>

    notes = []; ... postItem(Note item) async { ... } postItemImage(File file) async { ... } signInWithGoogle() async { ... } } firebase_service.dart
  13. import 'firebase_service.dart'; ... @Component( selector: 'my-app', templateUrl: 'app_component.html', directives: const

    [ ... ], providers: const [FirebaseService]) class AppComponent { // Here is the implementation } app_component.dart
  14. -> import 'firebase_service.dart'; ... @Component( selector: 'my-app', templateUrl: 'app_component.html', directives:

    const [ ... ], providers: const [FirebaseService]) class AppComponent { // Here is the implementation } app_component.dart
  15. @Component(...) class NotesComponent implements OnInit { FirebaseService service; List<Note> notes

    = []; NotesComponent(this.service); @override ngOnInit() { notes = service.notes; } } notes_component.dart
  16. -> -> @Component(...) class NotesComponent implements OnInit { FirebaseService service;

    List<Note> notes = []; NotesComponent(this.service); @override ngOnInit() { notes = service.notes; } } notes_component.dart
  17. <div id="notes"> <div *ngFor="let note of notes"> <h3 *ngIf="note.title?.isNotEmpty"> {{note.title}}

    </h3> <div> <p>{{note.text}}</p> ... </div> ... </div> </div> notes_component.html
  18. firebase-dart/.../app_interop.dart @JS('App') abstract class AppJsImpl { external String get name;

    external FirebaseOptions get options; external AuthJsImpl auth(); external DatabaseJsImpl database(); external PromiseJsImpl delete(); external StorageJsImpl storage([String url]); } package:js
  19. @JS('App') abstract class AppJsImpl { external String get name; external

    FirebaseOptions get options; external AuthJsImpl auth(); external DatabaseJsImpl database(); external PromiseJsImpl delete(); external StorageJsImpl storage([String url]); } firebase-dart/.../app_interop.dart -> package:js
  20. @JS('firebase.database') library firebase.database_interop; ... @JS('Database') abstract class DatabaseJsImpl { external

    AppJsImpl get app; ... external ReferenceJsImpl ref([String path]); ... } firebase-dart/.../database_interop.dart package:js
  21. Wrapper around interop Dart types package:firebase // How we use

    the library try { await childRef.remove(); } catch (e) { print("Error while deleting item, $e"); }
  22. package:firebase Wrapper around interop Allow-interop solved // Implementation in wrapper

    class bool forEach(action(DataSnapshot snapshot)) { var actionWrap = allowInterop((d) => action(...)); return jsObject.forEach(actionWrap); }
  23. package:firebase Wrapper around interop Dart Map vs Js Object null,

    num, bool, String are ok Conversion through JSON For Map or Iterable is js_util.dart
  24. + =