React Native Expo - atabegruslan/Notes GitHub Wiki

Tutorials

Simple start

1/ Install node

2/ Create new project

Either npx create-expo-app or npx create-react-native-app

Local Expo CLI has became preferred over the Global one: https://blog.expo.dev/the-new-expo-cli-f4250d8e3421
So npx create-expo-app xxx became preferred over expo init xxx

Eg: You can start a project like this:

npx create-expo-app@latest projectName --template blank

References

3/ Run

npx create-expo-app by default creates these scripts in package.json

"scripts": {
  "start": "expo start",
  "android": "expo start --android",
  "ios": "expo start --ios",
  "web": "expo start --web"
},

You can run using the Expo Go app from your phone, or with development build. The Expo Go option is simpler. So,
download Expo Go to your phone,
run npm run start or yarn start (A.K.A.: npx expo start)
scan the QR code from within the Expo Go app.

npx expo start vs npx expo run

start defaults to Expo Go.
If you press a or i after that, it will run in any attached simulators or devices.

run automatically runs prebuild under the hood.
It does everything in one command, eg: npx expo run:android

Though it also depends on whats in app.json and eas.json.

References

Development build

Various commands

References

Bare vs Expo

Bare means without using Expo nor Metro bundler (nor any other frameworks) to manage it for you. You create the native app and configure everything yourself.

Back in the days, Expo wasn't fully stable and had some drawbacks in terms of using native Code and modules but today most projects can be run in Expo really well.

https://docs.expo.dev/workflow/prebuild is used to adapt from Expo to bare. But not fully bare.

You can create and run an Expo app on Expo Go on your phone and emulator. But when you start working with native stuff you'll need a dev build

Local app compilation

To build your project locally you can use compile commands from Expo CLI which generates the android and ios directories: npx expo run:android npx expo run:ios The above commands compile your project, using your locally installed Android SDK or Xcode, into a debug build of your app.

These compilation commands initially run npx expo prebuild to generate native directories (android and ios) before building, if they do not exist yet. If they already exist, this will be skipped. You can also add the --device flag to select a device to run the app on — you can select a physically connected device or emulator/simulator. You can pass in --variant release (Android) or --configuration Release (iOS) to build a production build of your app. Note that these builds are not signed and you cannot submit them to app stores. To sign your production build, see Local app production.

Local builds with expo-dev-client

If you install expo-dev-client to your project, then a debug build of your project will include the expo-dev-client UI and tooling, and we call these development builds.

npx expo install expo-dev-client

To create a development build, you can use local app compilation commands (npx expo run:[android|ios]) which will create a debug build and start the development server.

Android Studio and xCode

It's advantageous to install xCode and Android Studio too.
Typical system requirements:
xCode needs ~50GB disk space, Android Studio needs ~20GB disk space. Overall, a Mac of ~200GB disk space.
Android Emulator typically needs 16GB RAM & 16GB disk space. Though 8GB of RAM can still cope.

References

Common things

Query

Push notification

Data management

Social media integration

Toast messages

Audio

At its most bare-basic

import { Audio } from 'expo-av';

async function playSound() {
  const { sound } = await Audio.Sound.createAsync( require('../assets/audio/xxx.wav') );
  await sound.playAsync();
}

<Button title="Play Sound" onPress={playSound} />

Camera

Forms

Keyboard Avoidance

OS specific frontend styling

Paypal integration

This tutorial is for RN Cli: https://www.npmjs.com/package/react-native-paypal - react-native link react-native-paypal generates android & ios folders

This tutorial is for Expo: https://chatgpt.com/share/d1c838b8-2e6e-4f89-92b6-d603d2a3f176 - expo eject generates android & ios folders

Routers and navigators

How to solve this problem ("RNCSafeAreaProvider was not found in the UIManager Error") when using Expo Drawer Nav ( https://docs.expo.dev/router/advanced/drawer )

{
  "name": "drawers",
  "version": "1.0.0",
  "main": "expo-router/entry",
  "scripts": {
    "start": "expo start",
    "android": "expo start --android",
    "ios": "expo start --ios",
    "web": "expo start --web"
  },
  "dependencies": {
    "@react-native-community/masked-view": "^0.1.11",
    "@react-navigation/drawer": "^6.7.2",
    "expo": "~51.0.28",
    "expo-router": "^3.5.23",
    "expo-status-bar": "~1.12.1",
    "react": "18.2.0",
    "react-native": "0.74.5",
    "react-native-gesture-handler": "^2.18.1",
    "react-native-reanimated": "3.10.1",
    "react-native-safe-area-context": "^4.10.9",
    "react-native-screens": "^3.34.0"
  },
  "devDependencies": {
    "@babel/core": "^7.20.0"
  },
  "private": true
}
import { useRouter } from 'expo-router';
const router = useRouter();
router.back();

Deep Linking

Tabs

https://gist.github.com/atabegruslan/07fc9e556141b7a5e27c7ed7bf8a96c0

Render HTML

FlatList Infinite Scroll

Flash List

Payments

Open Phone's EMail App

import { SUPPORT_EMAIL } from '@/constants/Config';
import { Linking } from 'react-native';

export default function App() 
{
  const handleOpenEmail = () => {

    const email = `mailto:${SUPPORT_EMAIL}?subject=User query&body=Hello team,`;
    Linking.openURL( encodeURI(email) );
  };

  return (
    <View style={styles.container}>
      <Stack marginT-40>
        <Button
          onPress={handleOpenEmail}
        >
          {SUPPORT_EMAIL}
        </Button>

Publish

EAS

Pre-publish

npx expo-doctor@latest
Advice: Use 'npx expo install --check' to review and upgrade your dependencies.

1/ https://docs.expo.dev/workflow/prebuild 1a/ https://www.youtube.com/watch?v=2yHI0e4MzUE

If you are just using HTTPS REST API, Websockets and/or WebRTC, then just tick the standard option.

Test publish - Android

Google Play Console don't accept .apk anymore

Test publish - iOS

Different ways: https://developer.apple.com/help/app-store-connect/manage-builds/upload-builds

If you encounter this issue below, you need to agree to Apple's latest contract (2024).
https://stackoverflow.com/questions/78680844/ios-you-do-not-have-required-contracts-to-perform-an-operation
https://forums.developer.apple.com/forums/thread/710906

Before agreeing

After agreeing

Once you publish a build to App Store Connect's TestFlight:

  • Invite internal testers
  • Submit for Review
    • Give info such as Privacy and Contact Info and Screenshots,
    • Select a build (ie: version) from TestFlight,
  • Invite external testers

Giving Screenshots

What screenshot dimensions App Store Connect needs for review

So:

References:

Local builds

https://docs.expo.dev/build-reference/local-builds

Update

app.json

    "ios": {
      "supportsTablet": true,
      "bundleIdentifier": "com.yyy.xxx",
      "buildNumber": "1",
      "config": {
        "usesNonExemptEncryption": false
      }
    },
    "android": {
      "package": "com.yyy.xxx",
      "versionCode": 1,
      "adaptiveIcon": {
        "foregroundImage": "./assets/adaptive-icon.png",
        "backgroundColor": "#ffffff"
      }
    },

Update - Android

Increment versionCode!

When testing: Testing > Internal Testing > Create new release & add testers

When creating anew: (Todo)

This step isn't necessary

If you do it (Linking service account and downloading the key), you can then publish new releases automatically by: eas build --platform android then eas submit -p android --latest, with eas.json:

{
  ...
  "submit": {
    "production": {
      "android": {
        "serviceAccountKeyPath": "path to that downloaded key"
      }
    }
  }
}

If not, then just eas build --platform android, manually download build from expo.dev and upload to Google Play Console.

Update - iOS

Versions

Don't forget to update remote version too https://docs.expo.dev/build-reference/app-versions/#remote-version-source

So:
eas build:version:set to set Android versionCode and iOS buildNumber, and chose remote. eas.json will be updated.
eas build:version:sync

And don't forget to update:

  • android/app/build.gradle's versionCode and versionName
    • versionCode corresponds to app.json's Android versionCode
    • versionName corresponds to app.json's version
  • ios/{appname}/Info.plist's CFBundleVersion and CFBundleShortVersionString:
    • CFBundleVersion corresponds to app.json's iOS buildNumber
    • CFBundleShortVersionString corresponds to app.json's version

Others

Support

Google Play Developer support

https://support.google.com/googleplay/android-developer/gethelp?visit_id=638130374458737855-1460335542&rd=1&sjid=5078581807697071668-AP#

[email protected]

Apple

https://developer.apple.com

https://appstoreconnect.apple.com

Login at: https://idmsa.apple.com/appleauth/auth/signin

Apple support https://developer.apple.com/contact/topic/select

[email protected]


Theory

Metro; The JavaScript bundler for React Native:


Platform Specific

Audio

Android emulator control output volume

Android emulator control input microphone - Method 1

Android emulator control input microphone - Method 2

iOS simulator control output volume

iOS simulator control input microphone

https://stackoverflow.com/questions/3195739/turn-off-sound-in-iphone-simulator

Mac control input microphone

Start afresh

Android

Clear the emulator.

Open the android folder in Android Studio. Go to File > Invalidate Caches.

Or just delete app in emulator.

iOS

Delete app in simulator.

Reinstall all CocoaPods afresh: rm -rf node_modules; rm -rf ios/build; rm -rf ios/Pods; rm -rf ios/Podfile.lock; yarn; yarn podinstall.

Update Pods cd ios, then pod repo update, then pod install.

Or simple delete these folders: ios/build and ios/Pods.

PS: A Pod is a third-party library or framework that is integrated into a project using CocoaPods (CocoaPods is a dependency manager)

Android

Dealing with multiple gradles

When you run npx expo run:android, you can also see:

yarn run v1.22.22
$ expo run:android --variant debug
› Building app...
Downloading https://services.gradle.org/distributions/gradle-8.8-all.zip

iOS

iOS simulator use simulator's keyboard instead of Mac's keyboard

Screenshot

Run many Simulators

Firebase

Sometimes its faster to distribute builds among other developers during development phase

Upload

Drag & Drop the build file (eg: .apk) into Firebase, like any online dropbox.

Invite others

https://www.youtube.com/watch?v=V3z97mWuvmA&t=180s

⚠️ **GitHub.com Fallback** ⚠️