Share
Embed
React + Firebase
The presentation for GCPUG for Taiwan.
gcpugtw.kktix.cc/events/bfa4bc0a
Yuichiro MASUI
May 08, 2015
Transcript
72 slides
-
Nice to meet u. I’m Ichi • Yuichiro MASUI @masuidrive
• Toreta, Inc CTO / co-founder • Ruby, Javascript, Obj-C and many languages • Programming lover -
Questions If you have questions in this session, please tweet
with #GCPUG My hearing skill is poor :-p -
Firebase • One of BaaS (Backend as a Service) •
Realtime Database • Simple Login • Hosting -
Realtime database • NoSQL - JSON friendly database • Libraries:
Javascript (Browser/Node), iOS, Android • REST API • A lot of examples and tutorials -
Realtime database • NoSQL - JSON friendly database • Libraries:
Javascript (Browser/Node), iOS, Android • REST API • A lot of examples and tutorials { key1: “VAL1”, key2: “VAL2”, key3: { key4: “VAL4” } } -
Realtime database • NoSQL - JSON friendly database • Libraries:
Javascript (Browser/Node), iOS, Android • REST API • A lot of examples and tutorials { key1: “VAL1”, key2: “VAL2”, key3: { key4: “VAL4” } } GET “/key1” -
Realtime database • NoSQL - JSON friendly database • Libraries:
Javascript (Browser/Node), iOS, Android • REST API • A lot of examples and tutorials { key1: “VAL1”, key2: “VAL2”, key3: { key4: “VAL4” } } GET “/key1” “VAL1” -
Realtime database • NoSQL - JSON friendly database • Libraries:
Javascript (Browser/Node), iOS, Android • REST API • A lot of examples and tutorials { key1: “VAL1”, key2: “VAL2”, key3: { key4: “VAL4” } } GET “/key1” “VAL1” GET “/key3/key4” -
Realtime database • NoSQL - JSON friendly database • Libraries:
Javascript (Browser/Node), iOS, Android • REST API • A lot of examples and tutorials { key1: “VAL1”, key2: “VAL2”, key3: { key4: “VAL4” } } GET “/key1” “VAL1” GET “/key3/key4” “VAL4” -
Realtime database • NoSQL - JSON friendly database • Libraries:
Javascript (Browser/Node), iOS, Android • REST API • A lot of examples and tutorials -
API • Set / Get / Remove • Query •
Auth • Events -
Third Step • Manipulate database through from JS • Create
app with client side JS only -
Authenticate • Email / password • Social media login •
Google+, Facebook, GitHub, Twitter -
Why Firebase? • Almost web app is front end of
DB • Browser Javascript API • Security and role -
But • Hard to build realtime web app on Javascript
• DOM manipulation is too complex -
DOM is global variables <div id=“item-1”> <span id=“item-1-text” class=“hidden”>foo</span> </div>
DOM has state <button id=“add-item”>Add</a> Divided operations from DOM <div id=“item-1”> <span id=“item-1-text”>foo</span> </div> Anybody can change DOM -
Client side logic Synchronous web app Browser Logic = Controller
HTTP request Server User HTML generator (render) HTML generator (template engine) Generated state (setState) Generated state (template variables) -
Client side logic Browser Server User Event (onSubmit) React.js Server
side logic HTML generator (render) Generated state (setState) -
React.js • Javascript library for building UI • Born from
Facebook in ~2013 • Expanded to other companies • HipChat, AirBnB, Codecademy… -
Building UI • Just UI library • Components • Facebook
provide Flux architecture framework • One direction flow -
var App = React.createClass({ getInitialState: function(){ return({items:[”abc”, ”def”]}); }, render:
function() { return <div><ul> {this.state.items.map(function(item) { return <li>{item}</li> })} </ul></div>; } }); React.render(<App />, document.body); -
var App = React.createClass({ getInitialState: function(){ return({items:[”abc”, ”def”]}); }, render:
function() { return <div><ul> {this.state.items.map(function(item) { return <li>{item}</li> })} </ul></div>; } }); React.render(<App />, document.body); -
var App = React.createClass({ getInitialState: function(){ return({items:[”abc”, ”def”]}); }, render:
function() { return <div><ul> {this.state.items.map(function(item) { return <li>{item}</li> })} </ul></div>; } }); React.render(<App />, document.body); -
var App = React.createClass({ getInitialState: function(){ return({items:[”abc”, ”def”]}); }, render:
function() { return <div><ul> {this.state.items.map(function(item) { return <li>{item}</li> })} </ul></div>; } }); React.render(<App />, document.body); -
var App = React.createClass({ mixins: [ReactFireMixin], getInitialState: function(){ return({items:[]}); },
componentWillMount: function() { fb = new Firebase(this.props.url); this.bindAsArray(fb, "data"); this.firebaseRefs[“data"] .on("child_added", this.add.bind(this)); }, add: function(snapshot) { this.setState({ items: this.state.items.concat([snapshot.val()]) }); }, render: function() { return <div><ul> {this.state.items.map(function(item){ return <li>{item}</li> })} </ul></div>; } }); React.render(<App url=“https://demo.firebaseio.com/”/>, document.body); -
var App = React.createClass({ mixins: [ReactFireMixin], getInitialState: function(){ return({items:[]}); },
componentWillMount: function() { fb = new Firebase(this.props.url); this.bindAsArray(fb, "data"); this.firebaseRefs[“data"] .on("child_added", this.add.bind(this)); }, add: function(snapshot) { -
var App = React.createClass({ mixins: [ReactFireMixin], getInitialState: function(){ return({items:[]}); },
componentWillMount: function() { fb = new Firebase(this.props.url); this.bindAsArray(fb, "data"); this.firebaseRefs[“data"] .on("child_added", this.add.bind(this)); }, add: function(snapshot) { -
var App = React.createClass({ mixins: [ReactFireMixin], getInitialState: function(){ return({items:[]}); },
componentWillMount: function() { fb = new Firebase(this.props.url); this.bindAsArray(fb, "data"); this.firebaseRefs[“data"] .on("child_added", this.add.bind(this)); }, add: function(snapshot) { -
var App = React.createClass({ mixins: [ReactFireMixin], getInitialState: function(){ return({items:[]}); },
componentWillMount: function() { fb = new Firebase(this.props.url); this.bindAsArray(fb, "data"); this.firebaseRefs[“data"] .on("child_added", this.add.bind(this)); }, add: function(snapshot) { -
var App = React.createClass({ mixins: [ReactFireMixin], getInitialState: function(){ return({items:[]}); },
componentWillMount: function() { fb = new Firebase(this.props.url); this.bindAsArray(fb, "data"); this.firebaseRefs[“data"] .on("child_added", this.add.bind(this)); }, add: function(snapshot) { -
.on("child_added", this.add.bind(this)); }, add: function(snapshot) { this.setState({ items: this.state.items.concat([snapshot.val });
}, render: function() { return <div><ul> {this.state.items.map(function(item){ return <li>{item}</li> })} </ul></div>; } }); -
.on("child_added", this.add.bind(this)); }, add: function(snapshot) { this.setState({ items: this.state.items.concat([snapshot.val });
}, render: function() { return <div><ul> {this.state.items.map(function(item){ return <li>{item}</li> })} </ul></div>; } }); -
.on("child_added", this.add.bind(this)); }, add: function(snapshot) { this.setState({ items: this.state.items.concat([snapshot.val });
}, render: function() { return <div><ul> {this.state.items.map(function(item){ return <li>{item}</li> })} </ul></div>; } }); -
.on("child_added", this.add.bind(this)); }, add: function(snapshot) { this.setState({ items: this.state.items.concat([snapshot.val });
}, render: function() { return <div><ul> {this.state.items.map(function(item){ return <li>{item}</li> })} </ul></div>; } }); -
One direction flow • Can’t read DOM. Only write. $(“#count”).val($(“#count”).val()
+ 1); $(“#item”).toggle(“visible”); -
One direction flow • Can’t read value of <input/> <input
value={this.state.email} onChange={handle} /> handle: function(event) { this.setState({email: event.target.value}); } -
One direction flow • Can’t read value of <input/> <input
value={this.state.email} onChange={handle} /> handle: function(event) { this.setState({email: event.target.value}); } -
One direction flow • Can’t read value of <input/> <input
value={this.state.email} onChange={handle} /> handle: function(event) { this.setState({email: event.target.value}); } -
handleUpdateText: function(e) { this.setState({ newText: e.target.value }); }, handlePost: function(e)
{ this.firebaseRefs[“data”].push(this.state.newText); this.setState({newText: “”}); }, render: function() { return <div> <ul> {this.state.items.map(function(item){ return <li>{item}</li> })} </ul> <textarea value={this.state.newText} onChange={this.handleUpdateText} /> <button onClick={this.handlePost}>Post</button> </div>; } -
<ul> {this.state.items.map(function(item){ return <li>{item}</li> })} </ul> <textarea value={this.state.newText} onChange={this.handleUpdateText} />
<button onClick={this.handlePost}>Post< iv>; -
` <ul> {this.state.items.map(function(item){ return <li>{item}</li> })} </ul> <textarea value={this.state.newText} onChange={this.handleUpdateText}
/> <button onClick={this.handlePost}>Post< iv>; -
handleUpdateText: function(e) { this.setState({ newText: e.target.value }); }, handlePost: function(e)
{ this.firebaseRefs[“data”].push(this.state.newText); this.setState({newText: “”}); }, render: function() { return <div> <ul> {this.state.items.map(function(item){ return <li>{item}</li> })} </ul> <textarea value={this.state.newText} onChange={this.handleUpdateText} /> <button onClick={this.handlePost}>Post</button> </div>; } -
handleUpdateText: function(e) { this.setState({ newText: e.target.value }); }, handlePost: function(e)
{ this.firebaseRefs[“data”].push(this.state.newText); this.setState({newText: “”}); }, render: function() { return <div> <ul> {this.state.items.map(function(item){ return <li>{item}</li> })} </ul> <textarea value={this.state.newText} onChange={this.handleUpdateText} /> <button onClick={this.handlePost}>Post</button> </div>; } -
handleUpdateText: function(e) { this.setState({ newText: e.target.value }); }, handlePost: function(e)
{ this.firebaseRefs[“data”].push(this.state.newText); this.setState({newText: “”}); }, render: function() { return <div> <ul> {this.state.items.map(function(item){ return <li>{item}</li> })} </ul> <textarea value={this.state.newText} onChange={this.handleUpdateText} /> <button onClick={this.handlePost}>Post</button> </div>; } -
handleUpdateText: function(e) { this.setState({ newText: e.target.value }); }, handlePost: function(e)
{ this.firebaseRefs[“data”].push(this.state.newText); this.setState({newText: “”}); }, render: function() { return <div> <ul> {this.state.items.map(function(item){ return <li>{item}</li> })} </ul> <textarea value={this.state.newText} onChange={this.handleUpdateText} /> <button onClick={this.handlePost}>Post</button> </div>; } -
Sample App • Keep collaborate journals app • React +
FireBase • https://bit.ly/gcpug0508 • http://github.com/masuidrive/journals • Not for production yet. Keep develop now. -
Wrap up • Firebase is realtime database provider • Can
build app with Javascript only • React.js is smart library and architecture for realtime web • React.js and Firebase have good combination