Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

How AngularDart & Firebase did an App together

1,126 views

Published on

Beyond seven mountain ranges, beyond seven rivers and beyond seven Google buildings lived a technology called Angular. One day it met another technology - Firebase and they decided to do an App together.

In this talk I will show you why AngularDart is a framework you should definitely take a look at and how you can use it together with Firebase to build great apps!

Published in: Engineering

How AngularDart & Firebase did an App together

  1. 1. How AngularDart & Firebase did an App together Jana Moudra @Janamou #dfua
  2. 2. @Janamou
  3. 3. JavaScript, TypeScript, Dart, Elm,... React, Angular, Ember.js, Preact, Vue.js, … ?
  4. 4. dartlang.org For building Web browser, server, command line, and mobile apps
  5. 5. flutter.io Flutter talk Saturday, 10:10 For building Web browser, server, command line, and mobile apps
  6. 6. But hey, isn’t Dart dead? NO
  7. 7. Sunday night... Dart 2.0 is close...
  8. 8. Easy to learn Optionally vs statically typed Compiles to JavaScript Tons of libraries in the SDK
  9. 9. main() { print("Hello #DFUA 2017!"); }
  10. 10. // Is null no undefined var sum; // Tools warn you int count = "Jana";
  11. 11. // Cascade operator Dog dog = new Dog() ..name = "Andy" ..age = 8;
  12. 12. this is always this no need to fix it!
  13. 13. + = webdev.dartlang.org/angular ? ?? ? ?
  14. 14. Google is using it! Jana Moudra @Janamou #dfua
  15. 15. $$$ at Google
  16. 16. AdWords, AdSense, AdMob Millions of lines of code 25-100% increase in development speed at Google
  17. 17. Componeeeeeents FTW!!!
  18. 18. Simple & reusable Not only view Services Router Directives HTTP Pipes Forms Components Testing
  19. 19. Great apps need a backend!
  20. 20. Needed Lots of implementation Database, File Upload, User accounts, Anonymous user, OAuth, Hosting ...
  21. 21. For a simple app...
  22. 22. Hello Firebase!
  23. 23. Realtime Database Authentication Cloud Storage Messaging Hosting ... firebase.google.com
  24. 24. DEMO TIME Jana Moudra @Janamou #dfua
  25. 25. Include Js SDK package:firebase package:angular +
  26. 26. <!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
  27. 27. -> 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>
  28. 28. import 'package:angular/angular.dart'; @Component( selector: 'my-app', templateUrl: 'app_component.html', directives: const [ ... ] ) class AppComponent { // Here is the implementation } app_component.dart
  29. 29. app_component.dart -> import 'package:angular/angular.dart'; @Component( selector: 'my-app', templateUrl: 'app_component.html', directives: const [ ... ] ) class AppComponent { // Here is the implementation }
  30. 30. <div> <layout-header></layout-header> <main> <div id="container"> <new-note></new-note> <notes></notes> </div> <layout-footer></layout-footer> </main> </div> app_component.html
  31. 31. app_component.html -> <div> <layout-header></layout-header> <main> <div id="container"> <new-note></new-note> <notes></notes> </div> <layout-footer></layout-footer> </main> </div>
  32. 32. @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
  33. 33. 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 }
  34. 34. <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
  35. 35. Sign in with Google Read from realtime database Save to realtime database Upload to storage
  36. 36. 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) ...
  37. 37. Structure the data { "notes" : { "-KUsbAq6445-ynO4lg6Z" : { "img_url" : "dart.png", "text" : "Is awesome!", "title" : "Dart" }, ... } }
  38. 38. 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
  39. 39. DatabaseReference dbRef = database().ref("notes"); try { await dbRef .push({"text": "New note!!!"}) .future; } catch (e) { print("Error in writing to database: $e"); }
  40. 40. 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"); }
  41. 41. Where should I put Firebase? Component? Which? Create a Service
  42. 42. 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
  43. 43. 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
  44. 44. -> 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
  45. 45. @Component(...) class NotesComponent implements OnInit { FirebaseService service; List<Note> notes = []; NotesComponent(this.service); @override ngOnInit() { notes = service.notes; } } notes_component.dart
  46. 46. -> -> @Component(...) class NotesComponent implements OnInit { FirebaseService service; List<Note> notes = []; NotesComponent(this.service); @override ngOnInit() { notes = service.notes; } } notes_component.dart
  47. 47. <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
  48. 48. github.com/Janamou/firebase-demo-ng angularnotesboard.firebaseapp.com codelabs.developers.google.com/codelab s/angulardart-firebase-web-app/#0 +
  49. 49. JavaScript array undefined object function null
  50. 50. firebase.google.com/docs/reference ` https://firebase.google.com/docs/reference/js/
  51. 51. @JS('firebase.app') library firebase.app_interop; import 'package:js/js.dart'; // Other imports... package:js firebase-dart/.../app_interop.dart
  52. 52. 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
  53. 53. @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
  54. 54. @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
  55. 55. Do I need to write this manually?! TypeScript types definition file? js_facade_gen library
  56. 56. Wrapper around interop Dart types package:firebase // How we use the library try { await childRef.remove(); } catch (e) { print("Error while deleting item, $e"); }
  57. 57. package:firebase // Implementation in wrapper class Future remove() => handleThenable(jsObject.remove()); Wrapper around interop Dart types Thenable to Future “magic”
  58. 58. 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); }
  59. 59. 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
  60. 60. + =
  61. 61. Productivity, performance, and stability
  62. 62. “Backend without implementing backend”
  63. 63. You can port any JavaScript library to Dart
  64. 64. Thank You! Questions? Jana Moudra @Janamou #dfua
  65. 65. ● https://www.flickr.com/photos/150218480 @N07/36351299136/, cc ● https://www.flickr.com/photos/7940758@ N07/35070879422/, cc ● https://www.flickr.com/photos/99008530 @N07/14918820302/, cc ● https://www.flickr.com/photos/98251082 @N00/6507508041/, cc Images

×