How
AngularDart & Firebase
did an App together
Jana Moudra @Janamou #DevFestCZ
@Janamou
JavaScript, TypeScript, Dart, Elm,...
React, Angular, Ember.js,
Preact, Vue.js, …
?
For building
Web browser, server, command line, and mobile apps
dartlang.org
For building
Web browser, server, command line, and mobile apps
flutter.io
Flutter talk
Today, 10:00
But hey, isn’t Dart dead?
NO
Sunday night...
Dart 2.0 is almost here...
Easy to learn
Optionally vs statically typed
Compiles to JavaScript
Tons of libraries in the SDK
main() {
print("Hello #DevFestCZ 2017!");
}
// Is null no undefined
var sum;
// Tools warn you
int count = "Jana";
// Cascade operator
new Dog()
..name = "Andy"
..age = 8;
this is always this
no need to fix it!
+
=
webdev.dartlang.org/angular
?
?
?
?
?
is using it!
@Janamou #DevFestCZ
at Google
$$$
at Google
AdWords, AdSense, AdMob
Millions of lines of code
25-100% increase in development speed
Componeeeeeents FTW!!!
Simple & reusable
Not only view
Services Router
Directives HTTP
Pipes Forms
Components Testing
github.com/dart-lang/angular_components
github.com/dart-lang/angular_components
...
Great apps
need a backend!
Needed
Lots of implementation
Database, File Upload, User accounts, Anonymous user, OAuth, Hosting ...
For a simple app...
Hello Firebase!
Realtime Database
Authentication
Cloud Storage
Messaging
Hosting
...
firebase.google.com
DEMO
TIME
@Janamou #DevFestCZ
Include Js SDK
package:firebase
package:angular
+
name: firebase_demo_ng
description: AngularDart and Firebase app
...
dependencies:
angular: ^4.0.0
angular_forms: ^1.0.0
firebase: ^4.0.0
...
pubspec.yaml
name: firebase_demo_ng
description: AngularDart and Firebase app
...
dependencies:
angular: ^4.0.0
angular_forms: ^1.0.0
firebase: ^4.0.0
...
->
->
pubspec.yaml
<!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
<!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
import 'package:angular/angular.dart';
@Component(
selector: 'my-app',
templateUrl: 'app_component.html',
directives: const [ ... ]
)
class AppComponent {
// Here is the implementation
}
app_component.dart
import 'package:angular/angular.dart';
@Component(
selector: 'my-app',
templateUrl: 'app_component.html',
directives: const [ ... ]
)
class AppComponent {
// Here is the implementation
}
app_component.dart
->
<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
<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
->
@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
@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
->
<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
function
null
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
@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('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?
+
=
Productivity, performance,
and stability
“Backend without
implementing backend”
You can port any JavaScript
library to Dart
Thank You!
Questions?
Jana Moudra @Janamou #DevFestCZ