Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

iOS Command PhaseScriptExecution failed - Assumptions about 'head' utility on the execution PATH #5801

Closed
2 of 10 tasks
efhan-the-unorthodox opened this issue Oct 20, 2021 · 9 comments · Fixed by #5805
Closed
2 of 10 tasks
Labels
Help: Needs Triage Issue needs additional investigation/triaging. Impact: Bug New bug report

Comments

@efhan-the-unorthodox
Copy link

efhan-the-unorthodox commented Oct 20, 2021

Issue

I am aware that this issue has been brought up before and I am very sure that I followed the documentation properly and I have also looked up on those issues that are related to my question.

So I installed the packages @react-native-firebase/app and @react-native-firebase/messaging because all I want to use Firebase is for Cloud Messaging. I followed the setup as indicated in the documentation and ran the usual pod install in the ios folder of my project. I also added an empty firebase.json file that was instructed here.

However, after doing all that, my build still fails. With the output saying:

The following build commands failed:
PhaseScriptExecution [CP-User]\ [RNFB]\ Core\ Configuration /Users/user/Library/Developer/Xcode/DerivedData/app-bqmcphduhmtknhflnzqxcjarabsv/Build/Intermediates.noindex/app.build/Debug-iphonesimulator/app.build/Script-3A3BA8C7294B359F516CA4D5.sh 

When I open the script that was stated in the output, it shows this:

#!/bin/sh
#!/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.app_data_collection_default_enabled
  _APP_DATA_COLLECTION_ENABLED=$(getFirebaseJsonKeyValue "$_JSON_OUTPUT_RAW" "app_data_collection_default_enabled")
  if [[ $_APP_DATA_COLLECTION_ENABLED ]]; then
    _PLIST_ENTRY_KEYS+=("FirebaseDataCollectionDefaultEnabled")
    _PLIST_ENTRY_TYPES+=("bool")
    _PLIST_ENTRY_VALUES+=("$(jsonBoolToYesNo "$_APP_DATA_COLLECTION_ENABLED")")
  fi

  # config.analytics_auto_collection_enabled
  _ANALYTICS_AUTO_COLLECTION=$(getFirebaseJsonKeyValue "$_JSON_OUTPUT_RAW" "analytics_auto_collection_enabled")
  if [[ $_ANALYTICS_AUTO_COLLECTION ]]; then
    _PLIST_ENTRY_KEYS+=("FIREBASE_ANALYTICS_COLLECTION_ENABLED")
    _PLIST_ENTRY_TYPES+=("bool")
    _PLIST_ENTRY_VALUES+=("$(jsonBoolToYesNo "$_ANALYTICS_AUTO_COLLECTION")")
  fi

  # config.analytics_collection_deactivated
  _ANALYTICS_DEACTIVATED=$(getFirebaseJsonKeyValue "$_JSON_OUTPUT_RAW" "analytics_collection_deactivated")
  if [[ $_ANALYTICS_DEACTIVATED ]]; then
    _PLIST_ENTRY_KEYS+=("FIREBASE_ANALYTICS_COLLECTION_DEACTIVATED")
    _PLIST_ENTRY_TYPES+=("bool")
    _PLIST_ENTRY_VALUES+=("$(jsonBoolToYesNo "$_ANALYTICS_DEACTIVATED")")
  fi

  # config.analytics_idfv_collection_enabled
  _ANALYTICS_IDFV_COLLECTION=$(getFirebaseJsonKeyValue "$_JSON_OUTPUT_RAW" "analytics_idfv_collection_enabled")
  if [[ $_ANALYTICS_IDFV_COLLECTION ]]; then
    _PLIST_ENTRY_KEYS+=("GOOGLE_ANALYTICS_IDFV_COLLECTION_ENABLED")
    _PLIST_ENTRY_TYPES+=("bool")
    _PLIST_ENTRY_VALUES+=("$(jsonBoolToYesNo "$_ANALYTICS_IDFV_COLLECTION")")
  fi

  # config.analytics_default_allow_ad_personalization_signals
  _ANALYTICS_PERSONALIZATION=$(getFirebaseJsonKeyValue "$_JSON_OUTPUT_RAW" "analytics_default_allow_ad_personalization_signals")
  if [[ $_ANALYTICS_PERSONALIZATION ]]; then
    _PLIST_ENTRY_KEYS+=("GOOGLE_ANALYTICS_DEFAULT_ALLOW_AD_PERSONALIZATION_SIGNALS")
    _PLIST_ENTRY_TYPES+=("bool")
    _PLIST_ENTRY_VALUES+=("$(jsonBoolToYesNo "$_ANALYTICS_PERSONALIZATION")")
  fi

  # config.perf_auto_collection_enabled
  _PERF_AUTO_COLLECTION=$(getFirebaseJsonKeyValue "$_JSON_OUTPUT_RAW" "perf_auto_collection_enabled")
  if [[ $_PERF_AUTO_COLLECTION ]]; then
    _PLIST_ENTRY_KEYS+=("firebase_performance_collection_enabled")
    _PLIST_ENTRY_TYPES+=("bool")
    _PLIST_ENTRY_VALUES+=("$(jsonBoolToYesNo "$_PERF_AUTO_COLLECTION")")
  fi

  # config.perf_collection_deactivated
  _PERF_DEACTIVATED=$(getFirebaseJsonKeyValue "$_JSON_OUTPUT_RAW" "perf_collection_deactivated")
  if [[ $_PERF_DEACTIVATED ]]; then
    _PLIST_ENTRY_KEYS+=("firebase_performance_collection_deactivated")
    _PLIST_ENTRY_TYPES+=("bool")
    _PLIST_ENTRY_VALUES+=("$(jsonBoolToYesNo "$_PERF_DEACTIVATED")")
  fi

  # 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.in_app_messaging_auto_colllection_enabled
  _FIAM_AUTO_INIT=$(getFirebaseJsonKeyValue "$_JSON_OUTPUT_RAW" "in_app_messaging_auto_collection_enabled")
  if [[ $_FIAM_AUTO_INIT ]]; then
    _PLIST_ENTRY_KEYS+=("FirebaseInAppMessagingAutomaticDataCollectionEnabled")
    _PLIST_ENTRY_TYPES+=("bool")
    _PLIST_ENTRY_VALUES+=("$(jsonBoolToYesNo "$_FIAM_AUTO_INIT")")
  fi

  # config.app_check_token_auto_refresh
  _APP_CHECK_TOKEN_AUTO_REFRESH=$(getFirebaseJsonKeyValue "$_JSON_OUTPUT_RAW" "app_check_token_auto_refresh")
  if [[ $_APP_CHECK_TOKEN_AUTO_REFRESH ]]; then
    _PLIST_ENTRY_KEYS+=("FirebaseAppCheckTokenAutoRefreshEnabled")
    _PLIST_ENTRY_TYPES+=("bool")
    _PLIST_ENTRY_VALUES+=("$(jsonBoolToYesNo "$_APP_CHECK_TOKEN_AUTO_REFRESH")")
  fi

  # config.crashlytics_disable_auto_disabler - undocumented for now - mainly for debugging, document if becomes useful
  _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+=("FirebaseCrashlyticsCollectionEnabled")
    _PLIST_ENTRY_TYPES+=("bool")
    _PLIST_ENTRY_VALUES+=("NO")
  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"

Project Files

Javascript

Click To Expand

package.json:

firebase.json for react-native-firebase v6:

{
    "react-native": {
        
    }
}

iOS

Click To Expand

ios/Podfile:

  • I'm not using Pods
  • I'm using Pods and my Podfile looks like:


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:

  • Platform that you're experiencing the issue on:
    • 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?
    • No


@efhan-the-unorthodox efhan-the-unorthodox added Help: Needs Triage Issue needs additional investigation/triaging. Impact: Bug New bug report labels Oct 20, 2021
@mikehardy
Copy link
Collaborator

Interesting - is there any output in the build log showing what the error was? That is our Xcode script but we need to see the actual error if possible.
I definitely don't see this with https://github.com/mikehardy/rnfbdemo/blob/master/make-demo.sh where I/we do most of our compile testing
Separately - I'd strongly recommend moving up to react-native 0.66.1 if possible - Xcode builds in general received a great deal of attention (by me personally!) between 0.64 and 0.66 (facebook/react-native#31941 / facebook/react-native#31480) and I wouldn't want one of the things solved there to create problems here. https://react-native-community.github.io/upgrade-helper/ can show the way, the upgrades should be pretty easy

@mikehardy
Copy link
Collaborator

head is unexpected. It looks like it is a web-based utility (to issue requests to servers) vs the BSD utility.
You might try re-arranging your path so head is the standard command-line utility for finding the first NNN lines of a file

@efhan-the-unorthodox
Copy link
Author

efhan-the-unorthodox commented Oct 20, 2021

head is unexpected. It looks like it is a web-based utility (to issue requests to servers) vs the BSD utility.

You might try re-arranging your path so head is the standard command-line utility for finding the first NNN lines of a file

What do you mean by re-arranging my path? Are you saying it could be because I'm using a web based utility which is the result of this error?
It could be the case considering how I run my iOS app is using npx react-native run-ios

So I might have to install react-native cli do I?

@mikehardy
Copy link
Collaborator

The binary first on your path named head is not the one we expect. We expect a standard bsd utils binary and instead it's some web thing

Open terminal to test it. Type 'which head' or 'whereis head' to see what's what. You can search web for this as well and it'll probably give some insight

@mikehardy
Copy link
Collaborator

https://ss64.com/osx/head.html

vs some utility you have installed that's doing the equivalent of this https://stackoverflow.com/questions/217955/how-to-do-a-http-head-request-from-the-windows-command-line

@mikehardy mikehardy changed the title iOS Command PhaseScriptExecution failed with a nonzero exit code iOS Command PhaseScriptExecution failed - Assumptions about 'head' utility on the execution PATH Oct 20, 2021
@efhan-the-unorthodox
Copy link
Author

The binary first on your path named head is not the one we expect. We expect a standard bsd utils binary and instead it's some web thing

Open terminal to test it. Type 'which head' or 'whereis head' to see what's what. You can search web for this as well and it'll probably give some insight

I ran which head from my terminal and it gave me this output. /Applications/XAMPP/xamppfiles/bin/head
I am not sure how I ended up with this head but to explain why it's tied to XAMPP is because I have Xampp on my computer that I use to access my local mysql db on phpmyadmin.

I think it could be because I set my default php path to go to XAMPP so I more or less think I have to change back to the default path on my computer. I'll see about that

mikehardy added a commit that referenced this issue Oct 21, 2021
It appears we have an expectation about what `head` binary will do,
and XAMMP at least bundles a different `head` which does not meet our
expectations.

This is a basic unix utility on all macs via the base install, so the full path to the
base install version should be a reasonable fix

Fixes #5801
@mikehardy
Copy link
Collaborator

I made a PR to use the fully-specified path /usr/bin/head in our ios-config.sh script so this won't happen to anyone in the future. You can follow the link to the "patches" github action and download the patch set for use in patch-package if you want to try it now, or you can wait for the release (should be today, will be 12.9.3)

mikehardy added a commit that referenced this issue Oct 21, 2021
It appears we have an expectation about what `head` binary will do,
and XAMMP at least bundles a different `head` which does not meet our
expectations.

This is a basic unix utility on all macs via the base install, so the full path to the
base install version should be a reasonable fix

Fixes #5801
@efhan-the-unorthodox
Copy link
Author

efhan-the-unorthodox commented Oct 22, 2021

@mikehardy

Well, your hunch was right. Indeed it was a problem with the head or whatever you said it was. Apparently I decided to change my default php path to point to the one in xampp not knowing that it would have certain repercussions.
With this change, I can build my app without problems.

Thanks

@mikehardy
Copy link
Collaborator

I just published 12.9.3 https://github.com/invertase/react-native-firebase/blob/master/CHANGELOG.md#1293-2021-10-22 which should allow you to use XAMMP in the way you like without this build issue here

I see you've edited out the question about overriding iphone deployment versions. I'm only commenting on it to say: Oh, man! That was an odyssey to fix. But it is fixed in react-native 0.66.1 with at least a workaround that's easy to adopt, and in 0.67.0 (currently in -rc.0 status, but works) it's fixed for real. iOS compiles were a serious mess in react-native 0.64, 0.65 etc and it drove me crazy so yes, I did something about it ;-). Cheers

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Help: Needs Triage Issue needs additional investigation/triaging. Impact: Bug New bug report
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants