react native with expo

03/06/2020

Create

You must download the Expo application on your mobile device and register first

npm install -g expo-cli
expo-cli init  --template blank
cd 
mkdir src src/components src/screens src/api src/context
code .
npm start -c

open website and switch to tunnel.
Scan Qr Code to launch the app on your device

Copy an existing expo project

Copier le dossier.

Supprimer .expo-shared
Supprimer .git
Adapter app.json

Install in docker

its a standard node project.
we need "network_mode: host" to run multiple expo on the same server without hacks.
we need an entrypoint to login with expo (optional)

docker-compose.yml

yuddaoreact:
    build: ./yuddaoreact
    restart: always
    container_name: yuddaoreact
    volumes:
        - ./yuddaoreact:/usr/app/
    environment:
        - "TZ=Europe/paris"
        - "REACT_NATIVE_PACKAGER_HOSTNAME=raphaelpiccolo.com"
        - "EXPO_DEVTOOLS_LISTEN_ADDRESS=0.0.0.0"
        - "EXPO_USERNAME=martin.wb.2015@gmail.com"
        - "EXPO_PASSWORD=xxxxxxxxxxx"
    working_dir: /usr/app
    command: npm start
    network_mode: host

Dockerfile

FROM node
RUN apt-get update
RUN npm install -g expo-cli
WORKDIR /usr/app
COPY package*.json ./
RUN npm install
COPY . .
# expo login --non-interactive --username $EXPO_USERNAME --password $EXPO_PASSWORD && 
# CMD ["npm", "start"]
ENTRYPOINT ["/bin/sh", "entrypoint.sh"]
CMD ["npm", "start"]

entrypoint.sh

#!/bin/sh
expo login --non-interactive --username $EXPO_USERNAME --password $EXPO_PASSWORD
exec "$@"

add https with traefik (works but app doesnt launch)

#     environment:
#         - "EXPO_MANIFEST_PROXY_URL=https://expo.yuddao.com"
#         - "EXPO_PACKAGER_PROXY_URL=https://packager.yuddao.com"
#     labels:
#         - traefik.enable=true

#         - traefik.http.routers.yuddaoexpo.rule=Host(`expo.yuddao.com`)
#         - traefik.http.routers.yuddaoexpo.tls.certresolver=le
#         - traefik.http.routers.yuddaoexpo.entrypoints=websecure
#         - traefik.http.routers.yuddaoexpo.middlewares=securityheaders
#         - traefik.http.routers.yuddaoexpo.tls.options=notsafe@file
#         - traefik.http.routers.yuddaoexpo.service=yuddaoexpo
#         - traefik.http.services.yuddaoexpo.loadbalancer.server.port=19000

#         - traefik.http.routers.yuddaopackager.rule=Host(`packager.yuddao.com`)
#         - traefik.http.routers.yuddaopackager.tls.certresolver=le
#         - traefik.http.routers.yuddaopackager.entrypoints=websecure
#         - traefik.http.routers.yuddaopackager.middlewares=securityheaders
#         - traefik.http.routers.yuddaopackager.tls.options=notsafe@file
#         - traefik.http.routers.yuddaopackager.service=yuddaopackager
#         - traefik.http.services.yuddaopackager.loadbalancer.server.port=19001

force ports

  • expo server : 19000

    this port appears in exp://xxxx:19000

    it can be forced with :

          echo '{ "manifestPort": 19005 }' > .exprc
  • packagerPort : 19001
    it can be forced with :

          cat app.json  | jq --arg port 19004 '.expo.packagerOpts += {port: $port}' > tmp && mv tmp app.json
  • devToolsPort : 19002
    cant be changed ?

Structure

assets/ node_modules/ src/ api/ (axio) components/ context/ screens/ App.js

React-Navigation :

React Navigation has recently released a major update to v5 with breaking changes.
We will not be using this version and will instead continue to use the current stable v4 release (As of now at v4.1.1)

  1. Install React Navigation

    npm install react-navigation

  2. Install Dependencies

    expo install react-native-gesture-handler react-native-reanimated react-native-screens react-native-safe-area-context @react-native-community/masked-view

  3. Install React Navigation Stack

    npm install react-navigation-stack @react-native-community/masked-view

  4. Start the app and clear cache with

    npm start -c

If you are still seeing errors and complaints about packages, do the following:

1. rm -r node_modules

2. rm package-lock.json

3. expo upgrade

4. npm install

5. npm start -c

build

add this in app.json

"ios": {
    "supportsTablet": true,
    "bundleIdentifier": "com.example.app",
    "buildNumber": "1.0.0"
},
"android": {
    "package": "com.example.app",
    "versionCode": 1
}

build it for android

expo build:android
apk
let expo create keystore

get keystore from expo server
save console output + files + backup it somewhere

expo fetch:android:keystore

build it for ios

activate push notifications :

  • Login to https://developer.apple.com/

  • Go to the “Certificates, Identifiers and Profiles” section

  • Select “App IDs” in the Identifiers section on the left column

  • Choose your app ID, edit it and check “Push Notifications”. Save changes

  • No need to generate the certificate

    expo build:ios
    archive
    give your apple id and password
    let expo handle everything

get ios certificates from expo server
save console output + files + backup it somewhere

expo fetch:ios:certs

to publish to the store you need to use one of theses soft : https://help.apple.com/app-store-connect/#/devb1c185036

use proxy for expo build / expo login

http_proxy=http://2i.raphaelpiccolo.com:3128 expo build:ios

build for android with google play signin (optimised build)

not tested

expo fetch:android:hashes
expo fetch:android:upload-cert
expo opt-in-google-play-signing

get android push notifications

tuto ici : https://docs.expo.io/push-notifications/using-fcm/
aller ici pour créer un projet : https://console.firebase.google.com/

activate firebase

  • In your new project console

  • click Add Firebase to your Android app

  • set android package name like in app.json.

  • Download the google-services.json file and place it in your Expo app's root directory.

  • update app.json

      {
        ...
        "android": {
          "googleServicesFile": "./google-services.json",
          ...
        }
      }

publish key to expo

  • At the top of the sidebar, click the gear icon to the right of Project Overview to go to your project settings.

  • Click on the Cloud Messaging tab in the Settings pane.

  • copy the Server key and save it here google-services-serverkey.txt

  • run

      expo push:android:upload --api-key $(cat google-services-serverkey.txt)

iOs Simulator for screenshot

expo build:ios -t simulator

Download the tarball from expo.io

Unpack the tar.gz by running

tar -xvzf your-app.tar.gz

Rename your file in "project.app" if needded

Then you can run it by starting 3 different iOS Simulator

  • iphone 8 : 1242x2208
  • iphone 11 : 1242x2688
  • ipad Air 3eme gen : 2048x2732

Then run

xcrun simctl install booted  

It will install your app on one random simulator, so you can screen shot your different views with cmd+s

and

xcrun simctl launch booted .

ios add information on plist

describe camera usage

if you need to define something in the plist file like so :

NSCameraUsageDescription
Allow Expo experiences to use your camera
NSContactsUsageDescription
Allow Expo experiences to access your contacts
NSLocationWhenInUseUsageDescription
Allow Expo experiences to use your location
NSMicrophoneUsageDescription
Allow Expo experiences to access your microphone
NSMotionUsageDescription
Allow Expo experiences to access your device's accelerometer
NSPhotoLibraryAddUsageDescription
Give Expo experiences permission to save photos
NSPhotoLibraryUsageDescription
Give Expo experiences permission to access your photos

you can add this in app.json

{
  "expo": {
    ...
    "ios": {
      ...
      "infoPlist": {
        "NSCameraUsageDescription": "This app uses the camera to scan barcodes on event tickets."
      },
    },
},