# MAAGApp Mobile App

## 1. Setup
### 1.1 Compatibility
To run this mobile app, we need to have node `8.x.x` installed.
To install and manage multiple versions of node, we can use [nvm](https://github.com/creationix/nvm)
We also need to have installed Ruby version 2.3.X to use Gem.

### 1.2 Install

Install [cocoapod](https://guides.cocoapods.org/using/getting-started.html)

Clone the repository and then install all dependencies by running the following command
```bash
nvm use
npm install
```
### 1.3 Run
To run on iOS simulator

pre install pod

```bash
npm run pod
```

or

```bash
cd ios
pod install
cd ../
npm run ios
```

#### Run specific scheme
```bash
npm run ios -- --scheme "Nixplay" --device "e32c0db8ed7e5ac2be743dcada78b57ac944fd6e"
```
or

```bash
npm run ios:rnd -- --simulator "iPhone X"
```

or

```bash
npm run ios:rnd -- --device "iPhone X"
```

```bash
npm run ios:qa -- --device "iPhone X"
```

To run on Android emulator
```bash
npm run android
```

To run the unit tests
```bash
npm test
```

To run the unit tests in watch mode
```bash
npm run test:watch
```
## 2. Deploying Alpha build (We will use this until we release to PROD)
### 2.1 Increment build number
Alpha build is built using the develop branch with only the build number set to `git rev-list --count develop`. To create a new alpha build simply run the following command to update build number and commit it:

Update package.json version
e.g

"version": "3.0.1"

1. run `jq -r '.version' package.json` to echo
1. `npm run create:release:branch` create release branch with version name
1. `npm run prerelease` bumped version code when release to qa
2. `git flow release finish` to close release branch


### 2.2 Release an iOS build
After running the prerelease script, we can release iOS build by running the following command:
```bash
npm run ios:release:alpha
```

### 2.3 Release an Android build
After running the prerelease script, we can release Android build by running the following command:
```bash
npm run android:release:alpha
```

## 3. Deploying to QA
### 3.1 Before you begin

#### 3.1.A Setup prpvisioning profile
You need to install Fabric app to your mac. You need a account with https://fabric.io/, ask `Kumar` / `James` to send an invite so an account on Fabric can be created. After creating an account you can download and install the Fabric app.

You need 2 passwords to successfully deploy the app to crashlytics 1) the passcode for decrypting developer certificates to use with match and 2) the password for **mobile@nix-digital.com** apple developer account. Again ask `Kumar` / `James` for these.

You also need to install Fastlane CLI. Run the following command to do so:
```bash
gem install fastlane -NV
```

#### 3.1.B sync certificat
If certificate is outdate/not be synced run the following  commnad to sync up from repo



`fastlane ios certificates --env=<env>`

e.g.
```bash
fastlane ios certificates --env=rnd
```

for specific type of cert

`fastlane ios read_dev_cert --env=<env>`
`fastlane ios read_adhoc_cert --env=<env>`
`fastlane ios read_appstore_cert --env=<env>`


### 3.2 Create release branch
You can either use gitflow or simply use git to create a new branch:
```bash
git flow release start <version>
```
or

```bash
git checkout -b release/<version>
```

### 3.3 Bump build number
Bump build number and run other prerelease scripts like npm install etc
```bash
npm run prerelease
```

### 3.3.1 Bump version number
```bash
npm --no-git-tag-version version [major|minor|patch] patch -m "Upgrade to version %s"
```

example output

``` bash
npm --no-git-tag-version version patch -m "Upgrade to version %s"
v0.1.2
[RNV] Versioning Android...
[RNV] Android updated
[RNV] Versioning iOS...
[RNV] iOS updated
[RNV] Amending...
[RNV] Adjusting Git tag...
[RNV] Done
```

### 3.4 Release to QA
Release iOS version to QA:

```bash
npm run ios:release:qa
```
Release Android version to QA:
```bash
npm run android:release:qa
```

#### 3.4.1 Extra command
Release to Alpha:

```bash
npm run ios:release:alpha
npm run android:release:alpha
```
<!-- ```
npm run ios:release:beta
npm run android:release:beta

npm run ios:release:qa
npm run android:release:qa
``` -->

### 3.5 Merge the release branch back to Develop and Master

## 4. Workflow
Always create a new git branch to work on a user story. After a user story is completed then commit the code and push your changes. Login to https://git.nixplay.ninja/ and create a **Merge Request**, make sure to assign it to someone. The assignee should review the code and discuss if any issues with the committer and if no issues then merge it back to the develop branch.

> Note: Please never use **--no-verify** when pushing your changes to any branch including feature branches.

### 4.1 Create a new branch
You can either create a new branch using `git` or use `gitflow` if you have that set up
To create and switch to a new branch you can:
```bash
git checkout -b <branch name>
```

Work on a user story and make sure to add unit tests to cover your changes and to fix any broken unit tests due to the changes made.

### 4.2 Commit your changes and create merge request
Continue to commit changes regularly but make sure all tests and eslint issues is fixed before pushing. If you think a user story is done then go to https://git.nixplay.ninja/ and create a new merge request and assign it to someone to merge.

> Note: Do not commit directly to master or develop branch unless the changes is minimal. This means changing this README file is okay to commit directly to develop branch or changing the padding of a component. Any changes that requires more changes than that should be committed to feature branch.

### 4.3 Merge back from develop branch often
When we are working on a feature branch we may diverge from the develop branch. To ensure what we are doing is as upto date as possible and also to avoid merge conflicts, we should merge develop branch to our feature branch as often as possible.

### 5 Update reducerVersion when modifying the index reducer
Whenever we modify `src/reducers/index.js` we should also make sure we update the reducerVersion in `src/config/ReduxPersist.js` to prevent the app from crashing.

## Troubleshooting
iOS error `No bundle url present`, can try:
- https://www.andrewcbancroft.com/2017/04/22/solving-react-natives-no-bundle-url-present-error/


iOS error related to bundle url, you can also try:
- Kill the existing bundler process and then run the bundler
	```bash
	watchman watch-del-all
	yarn cache clean
	npm start -- --reset-cache
	```

iOS error `Entry, :CFBundleIdentifier, Does Not Exist`, can try:
- Run
	```bash
	npm run build:ios
	```

Android stuck on splash screen, can try:
- Uninstall the app, then run
	```bash
	npm run android
	```

If you see a version mismatch error message then try running the following command:
```bash
npm run ios:reset
```

Android build failed

```
Could not find manifest-merger.jar ...
```

run `rm -rf $HOME/.gradle/caches`
run `./android/gradlew cleanBuildCache -p ./android`

## Update app icon with single command
``` bash
https://blog.bam.tech/developper-news/change-your-react-native-app-icons-in-a-single-command-line
```


# Testing Subscription
Library used: [react-native-iap](https://github.com/dooboolab/react-native-iap)

Subscription flow:
![Subscription Flow](https://miro.medium.com/max/1400/1*LuTwkpUazCzJugMaYBZm2Q.png)
Reference: https://medium.com/dooboolab/react-native-iap-v3-1259e0b0c017

### Creating subscription item for iOS
`Apple Store Connect` > `My Apps` > Select an App > `Features` > `In-App Purchases` > Create your item

__IMPORTANT:__ Your item need to be `Ready to Submit` in RND and QA for it to purchasable.

__IMPORTANT 2:__ Product ID is unique and is for all apps. Even if you delete the item, you still cannot create with the same product ID even in another env.

### Creating subscription item for Android
`Google Play Console` > Select an App > `Store presence` > `In-app products` > `Subscriptions` > Create your item

__NOTE:__ Once you activate the subscription item, there is no way to deactivate or delete.

### Setting up sandbox on iOS
Create an email address under:
`Apple Store Connect` > `Users and Access` > `Testers`

__Note:__ Cannot create with email that is used for existing appleID, you can create using a non-existing email address.
There will be no purchase related email sent for sandbox purchase.

### Setting up sandbox on Android
1. Make sure the email address you register for testing is the primary account in your phone.
	That means the account is the first ever account you use in your phone.
	If not, remove all gmail account, then login with that email.
	Or, create another user profile in your phone (if the function is enabled), and use the email address registered as a user
2. Add email address in `Google Play Console > Settings > Account Details > License Testing`
3. Add email address in one of the list in `Google Play Console > Manage email lists`
4. Open this url with the email account you register:
	- RND: `https://play.google.com/apps/testing/com.creedon.Nixplay.rnd`
	- QA: `https://play.google.com/apps/testing/com.creedon.Nixplay.qa`

__Extra:__ The enabled countries might matters. Go to ` App (RND / QA) > Store presence > Pricing & distribution > Countries`, and enable the country.

### Subscription renewal timing
There is no way to manually unsubscribe in iOS sandbox, need to wait.
For Android, can unsubsribe in playstore.
Here are the info for the timings:
- https://help.apple.com/app-store-connect/#/dev7e89e149d
- https://developer.android.com/google/play/billing/billing_testing#testing-renewals


# Trouble Shooting

## xcrun: error: unable to find utility "instruments", not a developer

- if you have the following error message
``` sh
Found Xcode project TestProject.xcodeproj
xcrun: error: unable to find utility "instruments", not a developer
tool or in PATH

Command failed: xcrun instruments -s
xcrun: error: unable to find utility "instruments", not a developer
tool or in PATH
```

```
sudo xcode-select -s /Applications/Xcode.app
xcode-select --install
```

## Gem::Ext::BuildError: ERROR: Failed to build gem native extension.

- if you have the following error

``` sh
Fetching json 1.8.1
Installing json 1.8.1 with native extensions
Gem::Ext::BuildError: ERROR: Failed to build gem native extension.

    current directory: /usr/local/rvm/gems/ruby-2.3.4/gems/json-1.8.1/ext/json/ext/generator
/usr/local/rvm/rubies/ruby-2.3.4/bin/ruby -r ./siteconf20180608-11801-sqv5ra.rb extconf.rb
creating Makefile

current directory: /usr/local/rvm/gems/ruby-2.3.4/gems/json-1.8.1/ext/json/ext/generator
make "DESTDIR=" clean

current directory: /usr/local/rvm/gems/ruby-2.3.4/gems/json-1.8.1/ext/json/ext/generator
make "DESTDIR="
compiling generator.c
In file included from generator.c:1:
./../fbuffer/fbuffer.h:175:47: error: too few arguments provided to function-like macro invocation
    VALUE result = rb_str_new(FBUFFER_PAIR(fb));
                                              ^
/usr/local/rvm/rubies/ruby-2.3.4/include/ruby-2.3.0/ruby/intern.h:798:9: note: macro 'rb_str_new' defined here
#define rb_str_new(str, len) __extension__ (    \
        ^
In file included from generator.c:1:
./../fbuffer/fbuffer.h:175:11: warning: incompatible pointer to integer conversion initializing 'VALUE' (aka 'unsigned
long') with an expression of type 'VALUE (const char *, long)' (aka 'unsigned long (const char *, long)')
[-Wint-conversion]
    VALUE result = rb_str_new(FBUFFER_PAIR(fb));
          ^        ~~~~~~~~~~
1 warning and 1 error generated.
make: *** [generator.o] Error 1

make failed, exit code 2

Gem files will remain installed in /usr/local/rvm/gems/ruby-2.3.4/gems/json-1.8.1 for inspection.
Results logged to /usr/local/rvm/gems/ruby-2.3.4/extensions/x86_64-darwin-16/2.3.0/json-1.8.1/gem_make.out

An error occurred while installing json (1.8.1), and Bundler cannot continue.
Make sure that `gem install json -v '1.8.1' --source 'https://rubygems.org/'` succeeds before bundling.
```

run the following command to update gem file
```
https://github.com/flori/json/issues/229
```

## 'config.h' file not found
Copy and paste the following commands
```
cd ./node_modules/react-native
./scripts/ios-install-third-party.sh
cd third-party/glog-0.3.4
./configure
cd ../../../..
```

## clean the cache

```bash
npm run clean
```

you can run any one of the command individually

```
watchman watch-del-all
rm -rf node_modules
npm cache clean
rm -rf android/build/
rm -rf ./android/app/build/
rm -rf ./android/.gradle/
rm -rf ./android/.idea/
rm -rf ./ios/build
rm -rf ~/Library/Developer/Xcode/DerivedData && npm install
```


## Android subscription `item not found` in RND and QA
Check the `Setting up sandbox on Android` section above
