41
React Native Developing an app similar to Uber in JavaScript

React Native: Developing an app similar to Uber in JavaScript

Embed Size (px)

Citation preview

React Native

Developing an app similar to Uber in JavaScript

Caio AriedeFull Stack Developer at Parasail.com

2/16/2017

github.com/caioariede

Topics● ECMAScript 6 (es6)● React● React Native● Develop an app similar to Uber

ES 62015

"Harmony"

ES6: Modules// lib/math.js

export function sum (x, y) { return x + y }

export var pi = 3.141593

// someApp.js

import * as math from "lib/math"

console.log("2π = " + math.sum(math.pi, math.pi))

ES6: Classesclass Circle extends Shape {

constructor (id, x, y, radius) {

super(id, x, y)

this.radius = radius

}

}

React

React: JSX

const element = (

<h1 className="greeting">

Hello, world!

</h1>

)

React: Componentsclass Welcome extends React.Component {

render() {

return <h1>Welcome, {this.props.name}</h1>;

}

}

// <Welcome name="Fulano" />

React: Stateclass Counter extends React.Component {

state = {counter: 0}

onClick() {

this.setState({counter: this.state.counter+1})

}

render() {

return <div>

<span>{this.state.counter}</span>

<button onClick={this.onClick}>add</button>

</div>

}

}

React: VirtualDOM

Component VirtualDOM DOM (Browser)

render

React Native

React Native: Who uses?

React Native: Features

● Native apps (native UI components)● No need to recompile every time● Reusable code for iOS and Android (80%)● Communication with native functions

○ Objective-C, Java

Fonte: https://speakerdeck.com/frantic/react-native-under-the-hood

Idea: App similar to Uber

● Login with Facebook● Geolocation (passenger)● Real-time updates (drivers)● Trace/display route● Nearest driver

Using only JavaScript

Dependencies

Getting Started

● npm install -g react-native-cli

● react-native init UberProject● react-native run-ios

Project dependencies

● firebase: backend/database● react-native-fbsdk: login with facebook● react-native-maps: native map components● geofire: location queries● mapbox: calculate routes

Firebase: what's?

● Backend as a service● Real-time database● Handles authentication

○ oAuth, Facebook, Google, etc.

Firebase: authentication

OAuth token

Check token

LoginonClick() {

LoginManager.logInWithReadPermissions(['public_profile']).then(result => {

if (!result.isCancelled) {

} else {

console.log('login: user cancelled')

}

})

}

onClick() {

LoginManager.logInWithReadPermissions(['public_profile']).then(result => {

if (!result.isCancelled) {

AccessToken.getCurrentAccessToken().then(tokenResult => {

return auth.signInWithCredential(

facebook.credential(tokenResult.accessToken))

}).catch(err => console.log('login error: ' + err))

} else {

console.log('login: user cancelled')

}

})

}

Idea: App similar to Uber

● Login with Facebook √● Geolocation (passenger)● Real-time updates (drivers)● Trace/display route● Nearest driver

Mapclass Map extends Component {

state = {

passengerPosition: {latitude: 0, longitude: 0},

}

render() {

return (

<MapView>

<Marker coordinate={this.state.passengerPosition} />

</MapView>

)

}

}

watchPassenger() {

const positionOptions = {

enableHighAccuracy: true,

}

navigator.geolocation.watchPosition(pos => {

this.updatePassengerPosition({latitude: pos.latitude,

longitude: pos.longitude})

}, positionOptions)

}

updatePassengerPosition(passengerPosition) {

this.setState({passengerPosition})

}

Geolocation

Saving location to FirebaseupdatePassengerPosition(passengerPosition) {

this.setState({passengerPosition})

const user = firebase.database().ref('users/' + this.userId)

user.update({passengerPosition})

}

Idea: App similar to Uber

● Login with Facebook √● Geolocation (passenger) √● Real-time updates (drivers)● Trace/display route● Nearest driver

Real-time updates of driverswatchDrivers() {

firebase.database().ref('drivers').on('child_changed', data => {

let drivers = this.state.drivers

drivers[driver.id] = {id: data.key, position}

this.setState({drivers})

})

}

Displaying drivers on maprenderDrivers() {

return this.state.drivers.map(driver => (

<Marker key={driver.id} coordinate={driver.position}

image={carIcon} />

))

}

Idea: App similar to Uber

● Login with Facebook √● Geolocation (passenger) √● Real-time updates (drivers) √● Trace/display route● Nearest driver

Destinationclass SetDestination extends MapMixin {

constructor(props) {

this.state.destinationPosition = randomPosition(

props.passengerPosition, 500) // 500 meters

}

renderDestinationPosition() {

return <Marker draggable image={markerIcon}

coordinate={this.state.destinationPosition} />

}

}

Trace routecalculateRoute() {

const mode = 'driving'

const origin = buildLngLat(this.state.pickupPosition)

const destination = buildLngLat(this.state.destinationPosition)

const accessToken = this.mapBoxAccessToken

const url = buildMapBoxUrl(mode, origin, destination, accessToken)

fetch(url).then(response => response.json()).then(json => {

this.setState({route: getCoordinates(json)})

}).catch(e => {

console.warn(e)

})

}

Display routerenderRoute() {

return (

<MapView.Polyline strokeWidth={4}

coordinates={[this.state.passengerPosition,

...this.state.route,

this.state.destinationPosition]} />

)

}

Idea: App similar to Uber

● Login with Facebook √● Geolocation (passenger) √● Real-time updates (drivers) √● Trace/display route √● Nearest driver

GeoFire

geofire

key1: 37,-122

key2: lat, lng

key3: lat, lng

geoFire.set("key1", [37, -122])

listener geoquery

lat, lngraio

geoquery

lat, lngraio

Notify current geoqueries

Nearest driverlet radius = 0.1 // 100m

let currentLocation = [

passengerPosition.latitude,

passengerPosition.longitude,

]

let geoQuery = this.geoFire.query({center: currentLocation, radius})

let driversFound = []

geoQuery.on('key_entered', (key, location, distance) => {

driversFound.push({key, location, distance})

})

watchDriversFound()

Nearest driverwatchDriversFound() {

if (driversFound.length === 0) {

geoQuery.updateCriteria({radius: radius + 0.1})

} else {

let minDistance = -1, nearestDriver = null

driversFound.forEach(driver => {

if (driver.distance < minDistance || minDistance === -1)

minDistance = driver.distance, nearestDriver = driver

})

this.setState({nearestDriver: driver})

}

}

Idea: App similar to Uber

● Login with Facebook √● Geolocation (passenger) √● Real-time updates (drivers) √● Trace/display route √● Nearest driver √

Questions?

caioariede

on github and twitter