- React Native / Expo
- Typescript
- Supabase
- Mapbox
yarn install
npx expo run:ios
1 - Run npx create-expo-stack@latest
, Follow SS
Alternatively, run npx create-expo-stack@latest LimeApp --expo-router --stylesheet
2 - Install rn mapbox -> https://rnmapbox.github.io/docs/install
expo install @rnmapbox/maps
3 - Update plugin section of app.json
with below
[
"@rnmapbox/maps",
{
"RNMapboxMapsDownloadToken": "sk.ey..",
"RNMapboxMapsVersion": "11.0.0"
}
]
4 - Go to https://www.mapbox.com/ and create an account, generate a token ( also select DOWNLOAD:READ ) and use that at app.json
instead of sk.ey..
5 - Run npx expo install expo-location
to install location service for expo and update plugin section of app.json
with below
[
"expo-location",
{
"locationWhenInUsePermission": "Show current location on map."
}
]
6 - Run npx expo prebuild --clean
to build native dependencies after installing mapbox
7 - Create .env
file at root and Use Default public token
from mapbox dashboard to use Mapbox related components. Don't forget to add .env
to .gitignore
file.
EXPO_PUBLIC_MAPBOX_KEY=pk.ey123...
8 - Create Map component and start using map in the App
-------------------- First Commit --------------------
9 - Create a json file with lat and long of scooters and update Map component to render scooter icons on the map with those lat and long
-------------------- Second Commit --------------------
10 - Add cluster
prop to the ShapeLayer, render CircleLayer
for clusters, Render the count of scooters in a cluster using SymbolLayer
, Hide Scooter Icons when in cluster filter={['!', ['has', 'point_count']]}
-------------------- Third Commit --------------------
11 - Create directions service to calculate routes between user location and selected scooter
12 - Update Map file to render directions on the map
-------------------- Forth Commit --------------------
13 - Refactor: Create ScooterProvider to move business logic to provider to reuse that later on
14 - Refactor: Create LineRoute and ScooterMarkers to simplfy Map component
-------------------- Fifth Commit --------------------
15 - Install https://gorhom.dev/react-native-bottom-sheet/
for bottom sheets
yarn add @gorhom/bottom-sheet@^5 react-native-reanimated react-native-gesture-handler
16 - Update plugin section of babel.config.js
const plugins = ['react-native-reanimated/plugin'];
17 - Add Start Journey button to sheet and make it disabled if scooter's distance more than 1000 mt
-------------------- Sixth Commit --------------------
18 - Setup Supabase project called LimeApp
19 - Install supabase packages -> https://supabase.com/docs/guides/getting-started/tutorials/with-expo-react-native
npx expo install @supabase/supabase-js @react-native-async-storage/async-storage @rneui/themed
20 - Follow documents to Install and configure supabase libs in React Native
21 - Follow documents to Setup Auth Provider and routers to implement authentication
22 - SUPABASE: Go to Authentication/providers, select email and toggle off confirm email and save to let user signup without confirming email
-------------------- Seventh Commit --------------------
23 - SUPABASE: Follow -> https://supabase.com/docs/guides/database/extensions/postgis?language=js&queryGroups=language to use GEO data in Postgres with PostGiS (extensions is the one not gis)
24 - SUPABASE: Run below command at SQL Editor
section to create a new table
create table if not exists public.scooters (
id int generated by default as identity primary key,
location geography(POINT) not null,
battery float default 0
);
25 - SUPABASE: Run below command at SQL Editor
section to create geo index
create index scooters_geo_index
on public.scooters
using GIST (location);
26 - SUPABASE: Run below command at SQL Editor
section to insert scooter locations
insert into public.scooters(location)
values
(st_point(-122.4115, 37.795)),
(st_point(-122.395, 37.793)),
(st_point(-122.4135, 37.797)),
...,
...,
(st_point(-122.4, 37.775));
27 - SUPABASE: Run below command at SQL Editor
section to create the nearby_scooters
SQL function
create or replace function nearby_scooters(lat float, long float, max_dist_meters float)
returns table (id public.scooters.id%TYPE, battery public.scooters.battery%TYPE, lat float, long float, dist_meters float)
language sql
as $$
select id, battery, st_y(location::geometry) as lat, st_x(location::geometry) as long, st_distance(location, st_point(long, lat)::geography) as dist_meters
from public.scooters
where st_dwithin(location, st_point(long, lat)::geography, max_dist_meters)
order by location <-> st_point(long, lat)::geography;
$$;
28 - Add below function to ScooterProvider to fetch nearby scooters
// rpc = remote procedure call
const { error, data } = await supabase.rpc('nearby_scooters', {
lat: location.coords.latitude,
long: location.coords.longitude,
max_dist_meters: 2000,
});
-------------------- Eighth Commit --------------------
29 - SUPABASE: Create table called rides
and add user_id
and scooter_id
with their foregn keys, finished_at
with timestamptz
type
30 - Add policies for rides table
- Enable insert for authenticated use (INSERT)
- Enable read access for all users (SELECT)
- Enable update for users based on user_id (UPDATE) - used delete policy and changed to update
31 - Add RideProvider
and ActiveRideSheet
to track rides and show different active ride bottomsheet when user start a journey
-------------------- Ninth Commit --------------------
32 - Show/hide markers based on active ride status
-------------------- Tenth Commit --------------------
33 - SUPABASE: Add following column to rides
table, routeDuration - float8
, routeDistance - float8
and routeCoords - jsonb
34 - Track ride route and store it in database
-------------------- Eleventh Commit --------------------
Building an e-Scooter App with React Native and Mapbox Lime Clone Backend with React Native and Supabase