React + Firebase

React + Firebase

The presentation for GCPUG for Taiwan.
gcpugtw.kktix.cc/events/bfa4bc0a

0ec58a040e1e4e959c8566484b4bba19?s=128

Yuichiro MASUI

May 08, 2015
Tweet

Transcript

  1. 2.

    Nice to meet u. I’m Ichi • Yuichiro MASUI @masuidrive

    • Toreta, Inc CTO / co-founder • Ruby, Javascript, Obj-C and many languages • Programming lover
  2. 3.
  3. 4.
  4. 5.
  5. 6.
  6. 7.
  7. 8.
  8. 9.
  9. 10.
  10. 12.

    Questions If you have questions in this session, please tweet

    with #GCPUG My hearing skill is poor :-p
  11. 13.
  12. 14.

    Firebase • One of BaaS (Backend as a Service) •

    Realtime Database • Simple Login • Hosting
  13. 16.

    Realtime database • NoSQL - JSON friendly database • Libraries:

    Javascript (Browser/Node), iOS, Android • REST API • A lot of examples and tutorials
  14. 17.

    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” } }
  15. 18.

    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”
  16. 19.

    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”
  17. 20.

    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”
  18. 21.

    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”
  19. 22.

    Realtime database • NoSQL - JSON friendly database • Libraries:

    Javascript (Browser/Node), iOS, Android • REST API • A lot of examples and tutorials
  20. 33.
  21. 34.

    Why Firebase? • Almost web app is front end of

    DB • Browser Javascript API • Security and role
  22. 35.

    But • Hard to build realtime web app on Javascript

    • DOM manipulation is too complex
  23. 36.

    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
  24. 37.

    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)
  25. 38.

    Client side logic Browser Server User Event (onSubmit) React.js Server

    side logic HTML generator (render) Generated state (setState)
  26. 39.
  27. 40.

    React.js • Javascript library for building UI • Born from

    Facebook in ~2013 • Expanded to other companies • HipChat, AirBnB, Codecademy…
  28. 41.

    Building UI • Just UI library • Components • Facebook

    provide Flux architecture framework • One direction flow
  29. 42.

    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);
  30. 43.

    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);
  31. 44.

    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);
  32. 45.

    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);
  33. 46.

    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);
  34. 47.

    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) {
  35. 48.

    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) {
  36. 49.

    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) {
  37. 50.

    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) {
  38. 51.

    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) {
  39. 52.

    .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>; } });
  40. 53.

    .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>; } });
  41. 54.

    .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>; } });
  42. 55.

    .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>; } });
  43. 57.

    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}); }
  44. 58.

    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}); }
  45. 59.

    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}); }
  46. 60.

    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>; }
  47. 63.

    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>; }
  48. 64.

    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>; }
  49. 65.

    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>; }
  50. 66.

    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>; }
  51. 71.

    Sample App • Keep collaborate journals app • React +

    FireBase • https://bit.ly/gcpug0508 • http://github.com/masuidrive/journals • Not for production yet. Keep develop now.
  52. 72.

    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