React-native-firebase: CI build hangs on Running script '[CP-User] [RNFB] Core Configuration'

Created on 28 May 2020  ·  23Comments  ·  Source: invertase/react-native-firebase


Issue



On CI (bitrise) our iOS build is hanging 50% of the time on the ▸ Running script '[CP-User] [RNFB] Core Configuration' step. Android works fine. Rerunning the build also seems to fix it as it only happens 50% of the time.


Project Files






Javascript

Click To Expand

#### `package.json`:

# N/A
#### `firebase.json` for react-native-firebase v6:
# N/A
### iOS
Click To Expand

#### `ios/Podfile`: - [ ] I'm not using Pods - [x] I'm using Pods and my Podfile looks like:

# N/A
#### `AppDelegate.m`:
// N/A


Android

Click To Expand

#### Have you converted to AndroidX? - [ ] my application is an AndroidX application? - [ ] I am using `android/gradle.settings` `jetifier=true` for Android compatibility? - [ ] I am using the NPM package `jetifier` for react-native compatibility? #### `android/build.gradle`:

// N/A
#### `android/app/build.gradle`:
// N/A
#### `android/settings.gradle`:
// N/A
#### `MainApplication.java`:
// N/A
#### `AndroidManifest.xml`:
<!-- N/A -->


Environment

Click To Expand

**`react-native info` output:**

 OUTPUT GOES HERE
- **Platform that you're experiencing the issue on**: - [x] iOS - [ ] Android - [ ] **iOS** but have not tested behavior on Android - [ ] **Android** but have not tested behavior on iOS - [ ] Both - **`react-native-firebase` version you're using that has this issue:** - `e.g. 5.4.3` - **`Firebase` module(s) you're using that has the issue:** - `e.g. Instance ID` - **Are you using `TypeScript`?** - `Y/N` & `VERSION`




Build Error iOS

Most helpful comment

@hamidhadi in the root of a project. No, the script analyzes the file and apply the configuration to Info.plist

Example: firebase.json

{
  "react-native": {
    "crashlytics_auto_collection_enabled": false,
    "perf_auto_collection_enabled": false,
    "analytics_auto_collection_enabled": false
  }
}

All 23 comments

What's in the script at that line?

My experience with bitrise builds is that they have had lots of problems in the past, and all seemed like phantoms from the modules perspective, i.e., all strange bitrise platform issues :shrug: https://github.com/invertase/react-native-firebase/issues?q=is%3Aissue++bitrise

The only reproducible success has come from the submitter doggedly pursuing the thing, module maintainers (like me) here have had no effect unfortunately

#!/usr/bin/env bash
#
# Copyright (c) 2016-present Invertase Limited & Contributors
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this library except in compliance with the License.
# You may obtain a copy of the License at
#
#   http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
set -e
_MAX_LOOKUPS=2;
_SEARCH_RESULT=''
_RN_ROOT_EXISTS=''
_CURRENT_LOOKUPS=1
_JSON_ROOT="'react-native'"
_JSON_FILE_NAME='firebase.json'
_JSON_OUTPUT_BASE64='e30=' # { }
_CURRENT_SEARCH_DIR=${PROJECT_DIR}
_PLIST_BUDDY=/usr/libexec/PlistBuddy
_TARGET_PLIST="${BUILT_PRODUCTS_DIR}/${INFOPLIST_PATH}"
_DSYM_PLIST="${DWARF_DSYM_FOLDER_PATH}/${DWARF_DSYM_FILE_NAME}/Contents/Info.plist"
# plist arrays
_PLIST_ENTRY_KEYS=()
_PLIST_ENTRY_TYPES=()
_PLIST_ENTRY_VALUES=()
function setPlistValue {
  echo "info:      setting plist entry '$1' of type '$2' in file '$4'"
  ${_PLIST_BUDDY} -c "Add :$1 $2 '$3'" $4 || echo "info:      '$1' already exists"
}
function getFirebaseJsonKeyValue () {
  if [[ ${_RN_ROOT_EXISTS} ]]; then
    ruby -e "require 'rubygems';require 'json'; output=JSON.parse('$1'); puts output[$_JSON_ROOT]['$2']"
  else
    echo ""
  fi;
}
function jsonBoolToYesNo () {
  if [[ $1 == "false" ]]; then
    echo "NO"
  elif [[ $1 == "true" ]]; then
    echo "YES"
  else echo "NO"
  fi
}
echo "info: -> RNFB build script started"
echo "info: 1) Locating ${_JSON_FILE_NAME} file:"
if [[ -z ${_CURRENT_SEARCH_DIR} ]]; then
  _CURRENT_SEARCH_DIR=$(pwd)
fi;
while true; do
  _CURRENT_SEARCH_DIR=$(dirname "$_CURRENT_SEARCH_DIR")
  if [[ "$_CURRENT_SEARCH_DIR" == "/" ]] || [[ ${_CURRENT_LOOKUPS} -gt ${_MAX_LOOKUPS} ]]; then break; fi;
  echo "info:      ($_CURRENT_LOOKUPS of $_MAX_LOOKUPS) Searching in '$_CURRENT_SEARCH_DIR' for a ${_JSON_FILE_NAME} file."
  _SEARCH_RESULT=$(find "$_CURRENT_SEARCH_DIR" -maxdepth 2 -name ${_JSON_FILE_NAME} -print | head -n 1)
  if [[ ${_SEARCH_RESULT} ]]; then
    echo "info:      ${_JSON_FILE_NAME} found at $_SEARCH_RESULT"
    break;
  fi;
  _CURRENT_LOOKUPS=$((_CURRENT_LOOKUPS+1))
done
if [[ ${_SEARCH_RESULT} ]]; then
  _JSON_OUTPUT_RAW=$(cat "${_SEARCH_RESULT}")
  _RN_ROOT_EXISTS=$(ruby -e "require 'rubygems';require 'json'; output=JSON.parse('$_JSON_OUTPUT_RAW'); puts output[$_JSON_ROOT]" || echo '')
  if [[ ${_RN_ROOT_EXISTS} ]]; then
    _JSON_OUTPUT_BASE64=$(python -c 'import json,sys,base64;print(base64.b64encode(json.dumps(json.loads(open('"'${_SEARCH_RESULT}'"').read())['${_JSON_ROOT}'])))' || echo "e30=")
  fi
  _PLIST_ENTRY_KEYS+=("firebase_json_raw")
  _PLIST_ENTRY_TYPES+=("string")
  _PLIST_ENTRY_VALUES+=("$_JSON_OUTPUT_BASE64")
  # config.messaging_auto_init_enabled
  _MESSAGING_AUTO_INIT=$(getFirebaseJsonKeyValue "$_JSON_OUTPUT_RAW" "messaging_auto_init_enabled")
  if [[ $_MESSAGING_AUTO_INIT ]]; then
    _PLIST_ENTRY_KEYS+=("FirebaseMessagingAutoInitEnabled")
    _PLIST_ENTRY_TYPES+=("bool")
    _PLIST_ENTRY_VALUES+=("$(jsonBoolToYesNo "$_MESSAGING_AUTO_INIT")")
  fi
  # config.crashlytics_disable_auto_disabler - undocumented for now - mainly for debugging, document if becomes usful
  _CRASHLYTICS_AUTO_DISABLE_ENABLED=$(getFirebaseJsonKeyValue "$_JSON_OUTPUT_RAW" "crashlytics_disable_auto_disabler")
  if [[ $_CRASHLYTICS_AUTO_DISABLE_ENABLED == "true" ]]; then
    echo "Disabled Crashlytics auto disabler." # do nothing
  else
    _PLIST_ENTRY_KEYS+=("firebase_crashlytics_collection_enabled")
    _PLIST_ENTRY_TYPES+=("bool")
    _PLIST_ENTRY_VALUES+=("NO")
  fi
  # config.admob_delay_app_measurement_init
  _ADMOB_DELAY_APP_MEASUREMENT=$(getFirebaseJsonKeyValue "$_JSON_OUTPUT_RAW" "admob_delay_app_measurement_init")
  if [[ $_ADMOB_DELAY_APP_MEASUREMENT == "true" ]]; then
    _PLIST_ENTRY_KEYS+=("GADDelayAppMeasurementInit")
    _PLIST_ENTRY_TYPES+=("bool")
    _PLIST_ENTRY_VALUES+=("YES")
  fi
  # config.admob_ios_app_id
  _ADMOB_IOS_APP_ID=$(getFirebaseJsonKeyValue "$_JSON_OUTPUT_RAW" "admob_ios_app_id")
  if [[ $_ADMOB_IOS_APP_ID ]]; then
    _PLIST_ENTRY_KEYS+=("GADApplicationIdentifier")
    _PLIST_ENTRY_TYPES+=("string")
    _PLIST_ENTRY_VALUES+=("$_ADMOB_IOS_APP_ID")
  fi
else
  _PLIST_ENTRY_KEYS+=("firebase_json_raw")
  _PLIST_ENTRY_TYPES+=("string")
  _PLIST_ENTRY_VALUES+=("$_JSON_OUTPUT_BASE64")
  **echo "warning:   A firebase.json file was not found, whilst this file is optional it is recommended to include it to configure firebase services in React Native Firebase."**
fi;
echo "info: 2) Injecting Info.plist entries: "
# Log out the keys we're adding
for i in "${!_PLIST_ENTRY_KEYS[@]}"; do
  echo "    ->  $i) ${_PLIST_ENTRY_KEYS[$i]}" "${_PLIST_ENTRY_TYPES[$i]}" "${_PLIST_ENTRY_VALUES[$i]}"
done
for plist in "${_TARGET_PLIST}" "${_DSYM_PLIST}" ; do
  if [[ -f "${plist}" ]]; then
    # paths with spaces break the call to setPlistValue. temporarily modify
    # the shell internal field separator variable (IFS), which normally 
    # includes spaces, to consist only of line breaks
    oldifs=$IFS
    IFS="
"
    for i in "${!_PLIST_ENTRY_KEYS[@]}"; do
      setPlistValue "${_PLIST_ENTRY_KEYS[$i]}" "${_PLIST_ENTRY_TYPES[$i]}" "${_PLIST_ENTRY_VALUES[$i]}" "${plist}"
    done
    # restore the original internal field separator value
    IFS=$oldifs
  else
    echo "warning:   A Info.plist build output file was not found (${plist})"
  fi
done
echo "info: <- RNFB build script finished"`

I think it's this one? We don't have a firebase.json configured. If it runs sucessfully it gets to the bolded part, so it is hanging somewhere inbetween. Is there a way to skip this script if we don't use a firebase.json?

We're experiencing the same issue from time to time.

I mean this script does have a while true in there 🤔 No idea though, why the max lookups thing wouldn't bail then.

@boennemann also it prints information every iteration there (all 2 of them!) so it seems it would be easy to localize? Does bitrise use some terrible version of bash?

We have the same problem.

Also experiencing this issue.

This was on GH actions, during a build_app Fastlane step. Essentially, the command ran was:

set -o pipefail && xcodebuild -workspace workspace.xcworkspace -scheme scheme -destination 'generic/platform=iOS' -archivePath /Users/runner/Library/Developer/Xcode/Archives/2020-07-06/app\ 2020-07-06\ 19.51.01.xcarchive archive | tee /Users/runner/Library/Logs/gym/app.log | xcpretty

Everything seemed to build fine and it suddenly hangs at:

[19:55:44]: ▸ Processing Info.plist
[19:55:44]: ▸ Running script 'Bundle React Native code and images'
[19:55:49]: ▸     the transform cache was reset.
[19:56:56]: ▸ Generating 'app.app.dSYM'
[19:56:56]: ▸ Running script '[CP-User] [RNFB] Core Configuration'
[19:56:58]: ▸ Running script '[CP] Copy Pods Resources'
[19:57:00]: ▸ Running script '[CP-User] [RNFB] Crashlytics Configuration'

Actually, for me, it was that I wasn't running fastlane with setup_ci(force: true)

@Loopiezlol that tip might save lots of people time - we have a tips and tricks [edited: hit save too soon] page with an edit button - maybe a link to that fastlane docs page for CI users? with the error they would see

@mikehardy good shout, aiming to do so in the next couple of days

Actually, for me, it was that I wasn't running fastlane with setup_ci(force: true)

Doesn't work for me on bitrise :(

Hey guys,
Any update for this issue? We have the same issue on Bitrise and are not using Fastlane.

Unfortunately none of use these CI systems, we can only speak authoritatively and/or make fixes for the CI we use (github actions at this point). For all other CI systems, the community (you, us, we - not "them" or "someone") will have to experiment, try things etc and post PRs that work for you. We're happy to include things of course but can't come up with the fixes I don't think

@hamidhadi

I never used bitrise, but maybe something in here could be of help? https://devcenter.bitrise.io/troubleshooting/frequent-ios-issues/#a-step-hangs

one of the points in there mention:

Your script tries to access an item in the OS X Keychain and the item is configured to ask for permission before access (this is the default type of Access Control configuration if you add an item - for example a password - to Keychain)

I reckon this might be related somehow. I'm saying this as, with Fastlane, the setup_ci instruction which fixed my issue is essentially documented as:

setup_ci
Setup the keychain and match to work with CI
Creates a new temporary keychain for use with match
Switches match to readonly mode to not create new profiles/cert on CI
Sets up log and test result paths to be easily collectible
This action helps with CI integration. Add this to the top of your Fastfile if you use CI.

going down this rabbit hole, you can even check the exact implementation of that method: https://github.com/fastlane/fastlane/blob/master/fastlane/lib/fastlane/actions/setup_ci.rb#L26

keep in mind this is just a wild guess

yes in fact, I do fastlane builds on other macs in the house that I access by ssh sometimes, and this blocks my builds. I put this check in now as a fail fast early in my build:

before_all do
  # Make sure we have access to the keychain we use for certificates / codesign
  system "security show-keychain-info login.keychain > /dev/null 2>&1"
  UI.user_error! "login.keychain is locked, codesign will fail unless you run 'security unlock-keychain login.keychain'" unless $?.exits
tatus == 0
end

BTW, looks like that script freezing if can't find a file firebase.json.
I have added this file and now all works fine on Bitrise 🤷‍♂️

@vomchik The problem is it sometimes freezing sometimes not. 🤔
Where did you add the firebase.json file? From my understanding, it should be created by the script right?

@hamidhadi in the root of a project. No, the script analyzes the file and apply the configuration to Info.plist

Example: firebase.json

{
  "react-native": {
    "crashlytics_auto_collection_enabled": false,
    "perf_auto_collection_enabled": false,
    "analytics_auto_collection_enabled": false
  }
}

Anything that could help others would be a great addition here: https://rnfirebase.io/faqs-and-tips - edit button top right 🙏

Just chiming in to say that creating an empty firebase.json file on the root of the project unlocked my Bitrise build. Didn't want to change any values so I just left it empty like this.

{
  "react-native": {
  }
}

I'm experiencing the same on Github Actions. Adding firebase.json does not help.

@StijnCoolen unsure what might be the problem but this module's test app that runs our E2E CI tests is all in GitHub actions now, so we provide an example of how it might work if you browse through this repo

@mikehardy I will check it out, anything about keychain that should be added in particular? I tried your keychain before_alllane above.

I don't believe so - the keychain stuff for me is because I use fastlane to push builds to TestFlight, and fastlane stores Xcode cert info and passwords in the keychain so it needs access. If I do them headless (via ssh to one of the laptops I use to build some time, instead of logging in to macOS UI from the machine itself) the keychain is locked, and it may produce a hang but it's an obvious 🤦 type error you see in the build log in my experience

Was this page helpful?
0 / 5 - 0 ratings