Create your first React Application with Firebase

25 minutes
7 months, 2 weeks ago
<h3>Overview</h3><p>React is a JavaScript library for building user interfaces for the web. It is a very popular library and is maintained by Facebook and a community of individual developers and companies.</p><p>In this tutorial, you'll learn how to make a simple React application along with adding Firebase to your project.</p><h3>Source code</h3><p>As always, you can find the source for the complete project here :&nbsp;https://github.com/ashifa454/gitAllNews</p><h3>Prerequisite<br></h3><p>Basic Knowledge of React and Firebase.</p><h3>Getting Started</h3><p>1. Install create-react-app from npm, why CRAP because it’s easy to setup client side rendered react-application, and comes with all standard configuration required to get started.<br></p><pre>npm i -g create-react-app</pre><p><img src="https://i.imgur.com/uPGJRp2.png"><br></p><h3>Configure your Project</h3><p>Create a Project</p><pre>npx create-react-app &lt;app_name&gt;</pre><p>Use npx to in NPM v5.2+. It will generate a react project in your current directory. After initialization is done, run the command :&nbsp;</p><pre>cd &lt;app_name&gt;&nbsp;</pre><pre>run npm i  — save</pre><h3>Setup a Firebase Project</h3><p>Visit firebase.google.com, login to your console and setup a project with any name, once you are done initiating a project in firebase, you project console will look like this.</p><p><img src="https://i.imgur.com/IqJF50Q.png"><br></p><p>Next, go to your Project settings. Then, under Project overview, go to the integration tab and add a web project.&nbsp;</p><p>Once it is added you will see a jsonObject, save that as a file as we will need it later on in the tutorial.<br></p><p><img src="https://i.imgur.com/FHWScF8.png"><br></p><p><br></p><p><b>Install React-Router</b></p><p>In single page application native anchor tag cannot help to get the routing done, hence we are going to use a very famous library called react-router.</p><p>To install run this command&nbsp;in your project directory</p><pre>npm install --save react-router-dom&nbsp;</pre><p><b>Install Firebase for React</b></p><p>In your react project run&nbsp;</p><pre>npm i firebase  — save</pre><p>This will install the firebase javascript SDK in your project. You can check your package.json file for the same.</p><p>At this point, your project directory should look like this.</p><p><img src="https://i.imgur.com/G3mXd3Q.png"><br></p><p><br></p><p>Now that we are finally done with our setup, let's build the UI of the application.</p><p>I am going to use Bootstrap for this tutorial, but you can use anything you want.</p><p>To install bootstrap in your react project run</p><pre>npm install --save reactstrap react react-dom</pre><p><b>Setting up the router</b></p><p>In single page application router typically handles the routing to the different parts of the application, we have two main pages/components i.e, List News and Bookmarks, to we are going to setup this two routes in our application.</p><p>App.js</p><pre>import React, { Component } from 'react';<br>import {BrowserRouter as Router,Switch, Route} from 'react-router-dom';<br>import Main from './components/main';<br>import BookMarks from './components/bookmarks';<br>import four0four from './components/404';<br>import {auth} from './components/firebase';<br>class App extends Component {<br> constructor(){<br> super();<br> this.state={<br> user:JSON.parse(localStorage.getItem('user'))<br> }<br> }<br> render() {<br> return (<br> &lt;Router&gt;<br> &lt;Switch&gt;<br> &lt;Route component={()=&gt;&lt;Main user={this.state.user} /&gt;} path="/" user={this.state.user}&gt;&lt;/Route&gt;<br> &lt;Route component={BookMarks} path="/b/:userid" exact user={this.state.user}&gt;&lt;/Route&gt;<br> &lt;Route component={four0four}&gt;&lt;/Route&gt;<br> &lt;/Switch&gt;<br> &lt;/Router&gt;<br> );<br> }<br>}<br>export default App;</pre><p>As you have noted in component props we are not sending anything, we will need to create three main components to called whenever anyone visits these routes.&nbsp;</p><p>Note : a route without any path is considered as a default route and will be called in case of a 404 Error.</p><p>Create a components folder in src folder and create this three components.</p><p>newsCard.js</p><pre>import React, { Component } from 'react'<br>import {Col,Card,CardImg,CardBody,CardTitle,CardSubtitle,CardText,ButtonGroup,Button,CardFooter} from 'reactstrap';<br>export default class NewCard extends Component {<br> render() {<br> return (<br> &lt;Col lg={3} xs={12} sm={6} style={{paddingTop:'10px',paddingBottom:'10px'}}&gt;<br> &lt;Card&gt;<br> &lt;CardImg top width="100%" src="https://placeholdit.imgix.net/~text?txtsize=33&amp;txt=318%C3%97180&amp;w=318&amp;h=180" alt="Card image cap" /&gt;<br> &lt;CardBody&gt;<br> &lt;CardTitle&gt;{this.props.item.title}&lt;/CardTitle&gt;<br> &lt;CardSubtitle&gt;{this.props.item.authorName}&lt;/CardSubtitle&gt;<br> &lt;CardText&gt;{this.props.item.description}&lt;/CardText&gt;<br> &lt;/CardBody&gt;<br> &lt;CardFooter&gt;<br> &lt;ButtonGroup size="xs"&gt;<br> &lt;Button&gt;Visit&lt;/Button&gt;<br> &lt;Button&gt;Share&lt;/Button&gt;<br>&lt;/ButtonGroup&gt;<br> &lt;/CardFooter&gt;<br>&lt;/Card&gt;<br> &lt;/Col&gt;<br> )<br> }<br>}</pre><p>main.js</p><pre>import React, { Component } from 'react'<br>import NavBar from './navbar';<br>import {Container,Row} from 'reactstrap';<br>import NewsCard from './newsCard';<br>export default class Main extends Component {<br> constructor(){<br> super();<br> this.state={<br> news:[<br> {<br> title:'HELLO WORLD',<br> description:'HELLO WORLD',<br> url:'abc.com'<br> },{<br> title:'HELLO WORLD',<br> description:'HELLO WORLD',<br> url:'abc.com'<br> },{<br> title:'HELLO WORLD',<br> description:'HELLO WORLD',<br> url:'abc.com'<br> },{<br> title:'HELLO WORLD',<br> description:'HELLO WORLD',<br> url:'abc.com'<br> },<br> {<br> title:'HELLO WORLD',<br> description:'HELLO WORLD',<br> url:'abc.com'<br> },<br> {<br> title:'HELLO WORLD',<br> description:'HELLO WORLD',<br> url:'abc.com'<br> },<br> {<br> title:'HELLO WORLD',<br> description:'HELLO WORLD',<br> url:'abc.com'<br> },<br> {<br> title:'HELLO WORLD',<br> description:'HELLO WORLD',<br> url:'abc.com'<br> },<br> {<br> title:'HELLO WORLD',<br> description:'HELLO WORLD',<br> url:'abc.com'<br> }<br> ]<br> }<br> }<br> render() {<br> return (<br> &lt;div&gt;<br> &lt;NavBar user={this.props.user}/&gt;<br> &lt;Container style={{marginTop:'60px'}}&gt;<br> &lt;Row&gt;<br> {<br> this.state.news.map((item,index)=&gt;{<br> return &lt;NewsCard item={item}/&gt;<br> })<br> }<br> &lt;/Row&gt;<br> &lt;/Container&gt;<br> &lt;/div&gt;<br> )<br> }<br>}</pre><p>navbar.js</p><pre>import React, { Component } from 'react'<br>import {<br> Collapse,<br> Navbar,<br> NavbarToggler,<br> NavbarBrand,<br> Nav,<br> NavItem,Button,<br> NavLink,<br> UncontrolledDropdown,<br> DropdownToggle,<br> DropdownMenu,<br> DropdownItem } from 'reactstrap'; <br>import {auth,GoogleProvider} from './firebase';<br>export default class NavBar extends Component {<br> constructor(props) {<br> super(props);<p></p> this.toggle = this.toggle.bind(this);<br> this.state = {<br> isOpen: false,<br> };<br> }<br> toggle() {<br> this.setState({<br> isOpen: !this.state.isOpen<br> });<br> }<br> signInUsingGoogle=()=&gt;{<br> auth.signInWithPopup(GoogleProvider).then((result)=&gt;{<br> if(result!==null){<br> localStorage.setItem('user',JSON.stringify({<br> 'displayName':result.user.displayName,<br> 'uid':result.user.uid,<br> 'dp':result.user.photoURL<br> }))<br> }<br> }).catch(error=&gt;{<br> console.log('Something Wen Wrong')<br> })<br> }<br> render() {<br> return (<br> &lt;div&gt;<br> &lt;Navbar className="fixed-top" color="secondary" dark expand="md"&gt;<br> &lt;NavbarBrand href="/"&gt;GitAll News&lt;/NavbarBrand&gt;<br> &lt;NavbarToggler onClick={this.toggle} /&gt;<br> &lt;Collapse isOpen={this.state.isOpen} navbar&gt;<br> &lt;Nav className="ml-auto" navbar&gt;<br> {this.props.user? &lt;UncontrolledDropdown nav inNavbar&gt;<br> &lt;DropdownToggle nav caret&gt;<br> {this.props.user.displayName}<br> &lt;/DropdownToggle&gt;<br> &lt;DropdownMenu right&gt;<br> &lt;DropdownItem/&gt;<br> &lt;DropdownItem&gt;<br> Logout<br> &lt;/DropdownItem&gt;<br> &lt;/DropdownMenu&gt;<br> &lt;/UncontrolledDropdown&gt;:&lt;NavItem&gt;<br> &lt;NavLink&gt;<br> &lt;Button onClick={()=&gt;this.signInUsingGoogle()}&gt;Login with Google&lt;/Button&gt;<br> &lt;/NavLink&gt;<br> &lt;/NavItem&gt;}<br> &lt;/Nav&gt;<br> &lt;/Collapse&gt;<br> &lt;/Navbar&gt;<br> &lt;/div&gt;<br> )<br> }<br>}</pre><p>bookmarks.js</p><pre>import React, { Component } from 'react'<br>import NavBar from './navbar';<br>import {Container,Row} from 'reactstrap';<br>import NewsCard from './newsCard';<br>export default class BookMarks extends Component {<br> constructor(){<br> super();<br> this.state={<br> news:[<br> {<br> title:'HELLO WORLD',<br> description:'HELLO WORLD',<br> url:'abc.com'<br> },{<br> title:'HELLO WORLD',<br> description:'HELLO WORLD',<br> url:'abc.com'<br> },{<br> title:'HELLO WORLD',<br> description:'HELLO WORLD',<br> url:'abc.com'<br> },{<br> title:'HELLO WORLD',<br> description:'HELLO WORLD',<br> url:'abc.com'<br> },<br> {<br> title:'HELLO WORLD',<br> description:'HELLO WORLD',<br> url:'abc.com'<br> },<br> {<br> title:'HELLO WORLD',<br> description:'HELLO WORLD',<br> url:'abc.com'<br> },<br> {<br> title:'HELLO WORLD',<br> description:'HELLO WORLD',<br> url:'abc.com'<br> },<br> {<br> title:'HELLO WORLD',<br> description:'HELLO WORLD',<br> url:'abc.com'<br> },<br> {<br> title:'HELLO WORLD',<br> description:'HELLO WORLD',<br> url:'abc.com'<br> }<br> ]<br> }<br> }<br> render() {<br> return (<br> &lt;div&gt;<br> &lt;NavBar user={this.props.user}/&gt;<br> &lt;Container style={{marginTop:'60px'}}&gt;<br> &lt;Row&gt;<br> {<br> this.state.news.map((item,index)=&gt;{<br> return &lt;NewsCard item={item}/&gt;<br> })<br> }<br> &lt;/Row&gt;<br> &lt;/Container&gt;<br> &lt;/div&gt;<br> )<br> }<br>}</pre><p>Now that we are done with the UI of our application, let's add firebase authentication, database and news Api.&nbsp;<br></p><p><b>Add Firebase Authentication</b></p><p>Create a File firebase.js in src directory and add the firebase configuration that you saved in chapter one.</p><p>firebase.js</p><pre>import firebase from '@firebase/app';<br>import '@firebase/auth';<br>import 'firebase/firestore';<br>var config = {<br> apiKey: "CHANGE_WITH_YOUR_KEY",<br> authDomain: "AUTH_DOMAIN",<br> databaseURL: "DB_URL",<br> projectId: "PROJECT_ID",<br> storageBucket: "STORAGE_BUCKET",<br> messagingSenderId: "SENDER_ID"<br> };<br>firebase.initializeApp(config);<br>/* FIREBASE PROVIDERS */<br>const auth = firebase.auth();<br>const GoogleProvider = new firebase.auth.GoogleAuthProvider();<br>export {<br> auth,<br> GoogleProvider,<br>};</pre><p>main.js</p><pre>import React, { Component } from 'react'<br>import NavBar from './navbar';<br>import {Container,Row} from 'reactstrap';<br>import NewsCard from './newsCard';<br>export default class Main extends Component {<br> constructor(){<br> super();<br> this.state={<br> news:[]<br> }<br> }<br> componentDidMount(){<br> fetch('https://newsapi.org/v2/top-headlines?country=in&amp;apiKey=25fd2106bcbf49eaa4d02d0595371d80').then(response=&gt;response.json())<br> .then((data)=&gt;{<br> if(data.status=='ok'){<br> this.setState({<br> news:data.articles<br> })<br> }<br> })<br> .catch(err=&gt;{<br> alert(err)<br> })<br> }<br> render() {<br> return (<br> &lt;div&gt;<br> &lt;NavBar user={this.props.user}/&gt;<br> &lt;Container style={{marginTop:'60px'}}&gt;<br> &lt;Row&gt;<br> {<br> this.state.news.map((item,index)=&gt;{<br> return &lt;NewsCard item={item}/&gt;<br> })<br> }<br> &lt;/Row&gt;<br> &lt;/Container&gt;<br> &lt;/div&gt;<br> )<br> }<br>}</pre><p>newscard.js</p><pre>import React, { Component } from 'react'<br>import {Col,Card,CardImg,CardBody,CardTitle,CardSubtitle,CardText,ButtonGroup,Button,CardFooter} from 'reactstrap';<br>export default class NewCard extends Component {<br> render() {<br> return (<br> &lt;Col lg={3} xs={12} sm={6} style={{paddingTop:'10px',paddingBottom:'10px'}}&gt;<br> &lt;Card&gt;<br> &lt;CardImg top width="100%" height='150' src={this.props.item.urlToImage} alt={this.props.item.title} /&gt;<br> &lt;CardBody&gt;<br> &lt;CardTitle&gt;{this.props.item.title.substring(0,20)}&lt;/CardTitle&gt;<br> &lt;CardSubtitle&gt;{(this.props.item.author)?this.props.item.author:'NOT_AVAILABLE'}&lt;/CardSubtitle&gt;<br> &lt;CardText&gt;{this.props.item.description.substring(0,100)}&lt;/CardText&gt;<br> &lt;/CardBody&gt;<br> &lt;CardFooter&gt;<br> &lt;ButtonGroup size="xs"&gt;<br> &lt;Button href={this.props.item.url} target='_blank'&gt;Visit&lt;/Button&gt;<br> &lt;Button&gt;Bookmark&lt;/Button&gt;<br>&lt;/ButtonGroup&gt;<br> &lt;/CardFooter&gt;<br>&lt;/Card&gt;<br> &lt;/Col&gt;<br> )<br> }<br>}</pre><p>And that's it. Now we have successfully added Firebase Google Authentication, we will add NewsApi and we will add Further functionalities like Bookmark and sharing.</p><p>You can find the full repo here https://github.com/ashifa454/gitAllNews</p><h3>Deployment</h3><p><b>Build Your Project Using NPM</b></p><p>In your project directory run</p><pre>npm run build</pre><p>Once build is done, you will find a build folder which will contain the main project files to be hosted.</p><p><b>Setup Firebase Hosting</b></p><p>Go to your firebase project and choose hosting on left.&nbsp;</p><p>This will prompt you to install some tools e.g firebase-cli install all the required tools and initiate a firebase project.</p><p><img src="https://i.imgur.com/NcAtAqD.png"><br></p><p>After initiation, copy firebase json in root of your project.<br></p><p>firebase.json</p><pre>{<br> "hosting": {<br> "public": "build",<br> "ignore": [<br> "firebase.json",<br> "**/.*",<br> "**/node_modules/**"<br> ],<br> "rewrites": [<br> {<br> "source": "**",<br> "destination": "/index.html"<br> }<br> ]<br> }<br>}</pre><h3>Deploy</h3><p>Just Run Firebase deploy from your console and in some seconds you will able to the run your webapp like a pro.</p><p>https://gitall-11403.firebaseapp.com/&nbsp;</p><p>Check the link for final Output.<br></p><p><br></p><p><br></p>

Comments

You must login to comment