firebase-tools icon indicating copy to clipboard operation
firebase-tools copied to clipboard

Deploying Firebase Extension from GitHub action results in an error that Mobile SDK API is disabled

Open itsikbelson-spotlight opened this issue 3 years ago • 9 comments

[REQUIRED] Environment info

firebase-tools: 11.13.0 Platform: Ubuntu

[REQUIRED] Test case

N/A

[REQUIRED] Steps to reproduce

We're started using GitHub actions to deploy our extensions: firebase deploy --debug --only extensions We're using [email protected]

Our extensions (configured using manifests) include:

  • firestore-bigquery-export
  • firestore-send-email
  • mailchimp-firebase-sync

[REQUIRED] Expected behavior

Firebase extensions deploy complete successfully.

[REQUIRED] Actual behavior

We get the following error upon deployment: Mobile SDK API has not been used in project <PROJECT_ID> before or it is disabled. Enable it by visiting https://console.developers.google.com/apis/api/mobilesdk-pa.googleapis.com/overview?project=<PROJECT_ID> then retry. If you enabled this API recently, wait a few minutes for the action to propagate to our systems and retry. When I click the link I get a "Failed to load." error.

From reading a bit, I understand that Mobile SDK API is internal. None of the extensions seems to rely on the Mobile SDK API.

itsikbelson-spotlight avatar Oct 06 '22 13:10 itsikbelson-spotlight

@westarle might be able to add some info here too.

christhompsongoogle avatar Oct 10 '22 20:10 christhompsongoogle

Hey @itsikbelson-spotlight, I'm looking into this. 2 questions: 1 - Could you share your full debug log? 2 - You mentioned that you are deploying from a GH action. Does the same deploy work locally?

joehan avatar Oct 10 '22 22:10 joehan

1 - See relevant part of debug log below. 2 - Yes. It worked locally when running firebase deploy --debug --only extensions against the relevant Firebase project.

...
2022-10-06T12:50:23.3588993Z The following extension instances will be configured:
...
2022-10-06T12:50:23.3594137Z 	firestore-send-email (firebase/[email protected])
2022-10-06T12:50:23.3594726Z 	mailchimp-firebase-sync (mailchimp/[email protected])
2022-10-06T12:50:23.3595017Z 
2022-10-06T12:50:23.3595966Z [2022-10-06T12:50:23.356Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"]
2022-10-06T12:50:23.3597170Z [2022-10-06T12:50:23.356Z] [iam] checking project <PROJECT_ID> for permissions ["firebase.projects.get","firebaseextensions.instances.update"]
2022-10-06T12:50:23.3598275Z [2022-10-06T12:50:23.356Z] >>> [apiv2][query] POST https://cloudresourcemanager.googleapis.com/v1/projects/<PROJECT_ID>:testIamPermissions [none]
2022-10-06T12:50:23.3599559Z [2022-10-06T12:50:23.356Z] >>> [apiv2][(partial)header] POST https://cloudresourcemanager.googleapis.com/v1/projects/<PROJECT_ID>:testIamPermissions x-goog-quota-user=projects/<PROJECT_ID>
2022-10-06T12:50:23.3600999Z [2022-10-06T12:50:23.356Z] >>> [apiv2][body] POST https://cloudresourcemanager.googleapis.com/v1/projects/<PROJECT_ID>:testIamPermissions ***"permissions":["firebase.projects.get","firebaseextensions.instances.update"]***
2022-10-06T12:50:23.4770495Z [2022-10-06T12:50:23.476Z] <<< [apiv2][status] POST https://cloudresourcemanager.googleapis.com/v1/projects/<PROJECT_ID>:testIamPermissions 200
2022-10-06T12:50:23.4772016Z [2022-10-06T12:50:23.476Z] <<< [apiv2][body] POST https://cloudresourcemanager.googleapis.com/v1/projects/<PROJECT_ID>:testIamPermissions ***"permissions":["firebase.projects.get","firebaseextensions.instances.update"]***
2022-10-06T12:50:23.4775235Z [2022-10-06T12:50:23.477Z] >>> [apiv2][query] GET https://cloudbilling.googleapis.com/v1/projects/<PROJECT_ID>/billingInfo [none]
2022-10-06T12:50:23.6901526Z [2022-10-06T12:50:23.689Z] <<< [apiv2][status] GET https://cloudbilling.googleapis.com/v1/projects/<PROJECT_ID>/billingInfo 200
2022-10-06T12:50:23.6903222Z [2022-10-06T12:50:23.689Z] <<< [apiv2][body] GET https://cloudbilling.googleapis.com/v1/projects/<PROJECT_ID>/billingInfo ***"name":"projects/<PROJECT_ID>/billingInfo","projectId":"<PROJECT_ID>","billingAccountName":"billingAccounts/<ACCOUNT_ID>","billingEnabled":true***
2022-10-06T12:50:23.6911711Z [2022-10-06T12:50:23.690Z] >>> [apiv2][query] GET https://mobilesdk-pa.googleapis.com/v1/projects/<PROJECT_ID>/products [none]
2022-10-06T12:50:23.8351712Z [2022-10-06T12:50:23.834Z] <<< [apiv2][status] GET https://mobilesdk-pa.googleapis.com/v1/projects/<PROJECT_ID>/products 403
2022-10-06T12:50:23.8355632Z [2022-10-06T12:50:23.834Z] <<< [apiv2][body] GET https://mobilesdk-pa.googleapis.com/v1/projects/<PROJECT_ID>/products ***"error":***"code":403,"message":"Mobile SDK API has not been used in project <PROJECT_NUM> before or it is disabled. Enable it by visiting https://console.developers.google.com/apis/api/mobilesdk-pa.googleapis.com/overview?project=<PROJECT_NUM> then retry. If you enabled this API recently, wait a few minutes for the action to propagate to our systems and retry.","status":"PERMISSION_DENIED","details":[***"@type":"type.googleapis.com/google.rpc.Help","links":[***"description":"Google developers console API activation","url":"https://console.developers.google.com/apis/api/mobilesdk-pa.googleapis.com/overview?project=<PROJECT_NUM>"***]***,***"@type":"type.googleapis.com/google.rpc.ErrorInfo","reason":"SERVICE_DISABLED","domain":"googleapis.com","metadata":***"consumer":"projects/<PROJECT_NUM>","service":"mobilesdk-pa.googleapis.com"***]***
2022-10-06T12:50:23.8370060Z 
2022-10-06T12:50:23.8372459Z Error: HTTP Error: 403, Mobile SDK API has not been used in project <PROJECT_NUM> before or it is disabled. Enable it by visiting https://console.developers.google.com/apis/api/mobilesdk-pa.googleapis.com/overview?project=<PROJECT_NUM> then retry. If you enabled this API recently, wait a few minutes for the action to propagate to our systems and retry.
2022-10-06T12:50:23.8373866Z [2022-10-06T12:50:23.836Z] Error Context: ***
2022-10-06T12:50:23.8374390Z   "body": ***
2022-10-06T12:50:23.8374919Z     "error": ***
2022-10-06T12:50:23.8375442Z       "code": 403,
2022-10-06T12:50:23.8377148Z       "message": "Mobile SDK API has not been used in project <PROJECT_NUM> before or it is disabled. Enable it by visiting https://console.developers.google.com/apis/api/mobilesdk-pa.googleapis.com/overview?project=<PROJECT_NUM> then retry. If you enabled this API recently, wait a few minutes for the action to propagate to our systems and retry.",
2022-10-06T12:50:23.8378118Z       "status": "PERMISSION_DENIED",
2022-10-06T12:50:23.8378675Z       "details": [
2022-10-06T12:50:23.8379195Z         ***
2022-10-06T12:50:23.8379944Z           "@type": "type.googleapis.com/google.rpc.Help",
2022-10-06T12:50:23.8380469Z           "links": [
2022-10-06T12:50:23.8380990Z             ***
2022-10-06T12:50:23.8381725Z               "description": "Google developers console API activation",
2022-10-06T12:50:23.8382771Z               "url": "https://console.developers.google.com/apis/api/mobilesdk-pa.googleapis.com/overview?project=<PROJECT_NUM>"
2022-10-06T12:50:23.8383416Z             ***
2022-10-06T12:50:23.8383917Z           ]
2022-10-06T12:50:23.8384432Z         ***,
2022-10-06T12:50:23.8384940Z         ***
2022-10-06T12:50:23.8385661Z           "@type": "type.googleapis.com/google.rpc.ErrorInfo",
2022-10-06T12:50:23.8386243Z           "reason": "SERVICE_DISABLED",
2022-10-06T12:50:23.8386855Z           "domain": "googleapis.com",
2022-10-06T12:50:23.8387433Z           "metadata": ***
2022-10-06T12:50:23.8388042Z             "consumer": "projects/<PROJECT_NUM>",
2022-10-06T12:50:23.8388862Z             "service": "mobilesdk-pa.googleapis.com"
2022-10-06T12:50:23.8389389Z           ***
2022-10-06T12:50:23.8389899Z         ***
2022-10-06T12:50:23.8390397Z       ]
2022-10-06T12:50:23.8390884Z     ***
2022-10-06T12:50:23.8391374Z   ***,
2022-10-06T12:50:23.8391884Z   "response": ***
2022-10-06T12:50:23.8392415Z     "statusCode": 403
2022-10-06T12:50:23.8392944Z   ***
2022-10-06T12:50:23.8393446Z ***
2022-10-06T12:50:24.1184149Z npm ERR! code ELIFECYCLE
2022-10-06T12:50:24.1184531Z npm ERR! errno 1
2022-10-06T12:50:24.1216252Z npm ERR! gloww-backend@ deploy:extensions: `firebase deploy --debug --only extensions`
2022-10-06T12:50:24.1216743Z npm ERR! Exit status 1
2022-10-06T12:50:24.1217370Z npm ERR! 
2022-10-06T12:50:24.1217921Z npm ERR! Failed at the gloww-backend@ deploy:extensions script.
2022-10-06T12:50:24.1218572Z npm ERR! This is probably not a problem with npm. There is likely additional logging output above.
2022-10-06T12:50:24.1253924Z 
2022-10-06T12:50:24.1257318Z npm ERR! A complete log of this run can be found in:
2022-10-06T12:50:24.1259886Z npm ERR!     /home/runner/.npm/_logs/2022-10-06T12_50_24_121Z-debug.log

itsikbelson-spotlight avatar Oct 11 '22 19:10 itsikbelson-spotlight

Could you verify that the project number in the error message "Mobile SDK API has not been used in project <PROJECT_NUM> " matches your project? If not, it might be 563584335869 instead?

One possible cause of this is calls being pointed at the CLIs default project instead of your project.

joehan avatar Oct 11 '22 20:10 joehan

Could you verify that the project number in the error message "Mobile SDK API has not been used in project <PROJECT_NUM> " matches your project? If not, it might be 563584335869 instead?

One possible cause of this is calls being pointed at the CLIs default project instead of your project.

The <PROJECT_NUM> matches my project number.

itsikbelson-spotlight avatar Oct 11 '22 20:10 itsikbelson-spotlight

So, after digging through the code a bit, that API is used during extension deploy. When deploying extensions that use Firebase Auth, we make a call to that API to check if Auth has been provisioned on that project correctly (https://github.com/firebase/firebase-tools/blob/master/src/extensions/provisioningHelper.ts#L134). However, we're missing a call to ensure that it is enabled before we call it. I'll make a PR to do so shortly.

For now, you can work around this by enabling that API by clicking the link in the error message.

joehan avatar Oct 11 '22 21:10 joehan

So, after digging through the code a bit, that API is used during extension deploy. When deploying extensions that use Firebase Auth, we make a call to that API to check if Auth has been provisioned on that project correctly (https://github.com/firebase/firebase-tools/blob/master/src/extensions/provisioningHelper.ts#L134). However, we're missing a call to ensure that it is enabled before we call it. I'll make a PR to do so shortly.

For now, you can work around this by enabling that API by clicking the link in the error message.

Thanks @joehan . Clicking the link does not help. When I click the link I get a "Failed to load." error. From reading a bit, I understand that Mobile SDK API is internal.

itsikbelson-spotlight avatar Oct 12 '22 07:10 itsikbelson-spotlight

Talked to some folks who know more about that API, and realized that we shouldn't actually enable it on the user project - that call is meant to go to the CLI consumer project. I'll update my PR to make this a best effort call, but I'd still like to understand why its working in one environment but not Github Actions.

@itsikbelson-spotlight Could you share a little more about the Github action that you are using to deploy this? Is it a publicly available action, or something custom that you can share a minimal viable repro of?

joehan avatar Oct 13 '22 17:10 joehan

I can share some of the action code and relevnat scripts. It's not a public action. At the bottom of things, the action runs:

firebase deploy --debug --only extensions

Action relevant code:

  steps:
    - name: Setup node
      uses: actions/setup-node@v3
      with:
        node-version: 14

    - name: Install npm packages
      shell: bash
      run: npm ci
      working-directory: ${{ inputs.working-directory }}

    - name: Install Firebase
      shell: bash
      run: npm i firebase-tools@${{env.firebase-tools-version}} -g
...
    - name: Deploy APIs to Firebase project ${{ inputs.firebase-project-alias }}
      shell: bash
      run: npm run deploy:apis
      working-directory: ${{ inputs.working-directory }}
...
    - name: Deploy extensions to Firebase project ${{ inputs.firebase-project-alias }}
      shell: bash
      run: npm run deploy:extensions
      working-directory: ${{ inputs.working-directory }}
...

Relevant npm scripts:

...
      "deploy:apis": "firebase deploy --debug --force --only <FUNCTION_NAMES>,
      "deploy:extensions": "firebase deploy --debug --only extensions",
...

itsikbelson-spotlight avatar Oct 13 '22 18:10 itsikbelson-spotlight

@itsikbelson-spotlight Thanks for the GH action code. I set that up on a test repo (https://github.com/joehan/gh-action-test/actions/runs/3277388571/jobs/5394597350), but I haven't been able to reproduce the issue.

My best guess at this point is that the issue is related to how the GH action is authorizing. I did not run into this when using a token from firebase login:ci. What method are you using for authorization?

joehan avatar Oct 18 '22 22:10 joehan

I'm setting GOOGLE_APPLICATION_CREDENTIALS to a service account key (json format). If I'm missing permissions there, it would be great to know which permissions are missing.

itsikbelson-spotlight avatar Oct 19 '22 07:10 itsikbelson-spotlight

Changed these checks to be best effort, which should resolve this issue. Unfortunately, I wasn't able to repro the issue you were facing, even using GOOGLE_APPLICATION_CREDENTIALS+ a service account JSON. This code is meant to check that Firebase Auth is provisioned before deploying an extension that uses it - if you end up getting instance installation errors after this PR release, I'd recommend double checking that Firebase Auth has been set up on your project.

joehan avatar Oct 26 '22 16:10 joehan

Hi, we are getting the same error:

Error when checking App Developer TOS for xxx. This is expected if authenticated via a service account: FirebaseError: HTTP Error: 403, Firebase Extensions Terms of Service Private API has not been used in project xxx before or it is disabled. Enable it by visiting https://console.developers.google.com/apis/api/firebaseextensionstos-pa.googleapis.com/overview?project=xxx then retry. If you enabled this API recently, wait a few minutes for the action to propagate to our systems and retry.

...

Error: HTTP Error: 403, Mobile SDK API has not been used in project xxx before or it is disabled. Enable it by visiting https://console.developers.google.com/apis/api/mobilesdk-pa.googleapis.com/overview?project=xxx then retry. If you enabled this API recently, wait a few minutes for the action to propagate to our systems and retry.
[2023-08-24T07:51:19.965Z] Error Context: {
  "body": {
    "error": {
      "code": 403,
      "message": "Mobile SDK API has not been used in project xxx before or it is disabled. Enable it by visiting https://console.developers.google.com/apis/api/mobilesdk-pa.googleapis.com/overview?project=xxx then retry. If you enabled this API recently, wait a few minutes for the action to propagate to our systems and retry.",
      "status": "PERMISSION_DENIED",
      "details": [
        {
          "@type": "type.googleapis.com/google.rpc.Help",
          "links": [
            {
              "description": "Google developers console API activation",
              "url": "https://console.developers.google.com/apis/api/mobilesdk-pa.googleapis.com/overview?project=xxx"
            }
          ]
        },
        {
          "@type": "type.googleapis.com/google.rpc.ErrorInfo",
          "reason": "SERVICE_DISABLED",
          "domain": "googleapis.com",
          "metadata": {
            "consumer": "projects/xxx",
            "service": "mobilesdk-pa.googleapis.com"
          }
        }
      ]
    }
  },
  "response": {
    "statusCode": 403
  }
}

when deploying via github actions:

      - name: Decode Google Cloud Service Account key
        env:
          GCP_SA_KEY: ${{ secrets.GCP_SA_KEY }}
        run: |
          echo "$GCP_SA_KEY" | base64 -d > /tmp/creds.json
          echo "GOOGLE_APPLICATION_CREDENTIALS=/tmp/creds.json" >>"$GITHUB_ENV"

      - name: Deploy Firebase - functions
        run: |
          echo \"N\n\" | firebase deploy --only functions --interactive

      - name: Deploy Firebase except hosting
        run: |
          firebase deploy \
              --except functions,hosting \
              --project "$GOOGLE_CLOUD_PROJECT" \
              --debug

The project number matches the real project.

We started to have this problem the moment we added the extension googlecloud/[email protected].

Additional info:

  • the service account associate to that key has owner role
  • we are using npm install -g [email protected]
  • Firebase Auth has been enabled
  • we never run firebase deploy interactively only via CI

Any suggestions?

Thanks

Update

If I run the steps of the workflow locally logged as the same service account I get the same error.

If I run the steps of the workflow up to the GOOGLE_APPLICATION_CREDENTIALS and run firebase login, now on:

$ firebase deploy --only extensions --debug
...
? Do you accept the Firebase Extensions User Terms of Service? (Y/n) 

Running CI after the extension has been deployed leads to the same issue.

yellowhat avatar Aug 24 '23 08:08 yellowhat