Upload
jana-moudra
View
374
Download
4
Embed Size (px)
Citation preview
How
AngularDart & Firebase did an App together
Jana Moudra @Janamou #dfua
@Janamou
JavaScript, TypeScript, Dart, Elm,...
React, Angular, Ember.js, Preact, Vue.js, …
?
dartlang.org
For building Web browser, server, command line, and mobile apps
flutter.ioFlutter talk
Saturday, 10:10
For building Web browser, server, command line, and mobile apps
But hey, isn’t Dart dead?
NO
Sunday night...
Dart 2.0 is close...
Easy to learn
Optionally vs statically typed
Compiles to JavaScript
Tons of libraries in the SDK
main() {
print("Hello #DFUA 2017!");
}
// Is null no undefined
var sum;
// Tools warn you
int count = "Jana";
// Cascade operator
Dog dog = new Dog()
..name = "Andy"
..age = 8;
this is always this
no need to fix it!
+ =
webdev.dartlang.org/angular
? ?? ??
is using it!
Jana Moudra @Janamou #dfua
$$$ at Google
AdWords, AdSense, AdMob
Millions of lines of code
25-100% increase in development speed
at Google
Componeeeeeents FTW!!!
Simple & reusable
Not only viewServices Router
Directives HTTP Pipes Forms Components Testing
Great apps need a backend!
NeededLots of implementation
Database, File Upload, User accounts, Anonymous user, OAuth,
Hosting ...
For a simple app...
Hello Firebase!
Realtime Database
Authentication
Cloud Storage
MessagingHosting... firebase.google.com
DEMO
TIME
Jana Moudra @Janamou #dfua
Include Js SDK
package:firebase
package:angular
+
<!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
->
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>
import 'package:angular/angular.dart';
@Component(
selector: 'my-app',
templateUrl: 'app_component.html',
directives: const [ ... ]
)
class AppComponent {
// Here is the implementation
}
app_component.dart
app_component.dart
->
import 'package:angular/angular.dart';
@Component(
selector: 'my-app',
templateUrl: 'app_component.html',
directives: const [ ... ]
)
class AppComponent {
// Here is the implementation
}
<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
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>
@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
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}
<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
Sign in with Google
Read from realtime database
Save to realtime database
Upload to storage
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)
...
Structure the data{
"notes" : {
"-KUsbAq6445-ynO4lg6Z" : {
"img_url" : "dart.png",
"text" : "Is awesome!",
"title" : "Dart"
},
...
}
}
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
DatabaseReference dbRef = database().ref("notes");
try {
await dbRef
.push({"text": "New note!!!"})
.future;
} catch (e) {
print("Error in writing to database: $e");
}
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");
}
Where should I put Firebase?
Component? Which?
Create a Service
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
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
->
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
@Component(...)
class NotesComponent implements OnInit {
FirebaseService service;
List<Note> notes = [];
NotesComponent(this.service);
@override
ngOnInit() {
notes = service.notes;
}
}notes_component.dart
->
->
@Component(...)
class NotesComponent implements OnInit {
FirebaseService service;
List<Note> notes = [];
NotesComponent(this.service);
@override
ngOnInit() {
notes = service.notes;
}
}notes_component.dart
<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
github.com/Janamou/firebase-demo-ng
angularnotesboard.firebaseapp.com
codelabs.developers.google.com/codelabs/angulardart-firebase-web-app/#0
+
JavaScript
array
undefined
object functionnull
firebase.google.com/docs/reference
`
https://firebase.google.com/docs/reference/js/
@JS('firebase.app')
library firebase.app_interop;
import 'package:js/js.dart';
// Other imports...
package:js
firebase-dart/.../app_interop.dart
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
@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
@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
Do I need to write this
manually?!TypeScript types definition file?
js_facade_gen library
Wrapper around interop
Dart types
package:firebase
// How we use the library
try { await childRef.remove();} catch (e) { print("Error while deleting item, $e");}
package:firebase
// Implementation in wrapper class
Future remove() => handleThenable(jsObject.remove());
Wrapper around interop
Dart types
Thenable to Future “magic”
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);}
package:firebase
Wrapper around interop
Dart Map vs Js Objectnull, num, bool, String are okConversion through JSONFor Map or Iterable is js_util.dart
+ =
Productivity, performance, and stability
“Backend without implementing backend”
You can port any JavaScript library to Dart
Thank You! Questions?
Jana Moudra @Janamou #dfua
● 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