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

Cannot attach a debugger to Firebase Python Functions

Open johnnyoshika opened this issue 1 year ago • 15 comments

[REQUIRED] Environment info

firebase-tools: 12.9.1

Platform: Windows / macOS

[REQUIRED] Test case

Run emulator with --inspect-functions flag:

firebase emulators:start --project demo-project --inspect-functions

[REQUIRED] Steps to reproduce

Run emulator with --inspect-functions flag:

firebase emulators:start --project demo-project --inspect-functions

This message appears in the console:

>  Debugger attached.
!  --inspect-functions not supported for Python functions. Ignored.

[REQUIRED] Expected behavior

Debugger would attach to Python functions

[REQUIRED] Actual behavior

Receive a message in the Console that debugger is not supported

johnnyoshika avatar Mar 06 '24 19:03 johnnyoshika

Hey @johnnyoshika, thanks for reaching out. Currently, --inspect-functions is only supported for Node.js runtimes. I’m going to label this as a feature request so we can better track this.

For those who also find this feature valuable, please leave a thumbs up on the original post. This helps our engineers prioritize future development efforts.

aalej avatar Mar 07 '24 13:03 aalej

As a workaround, I tried to debug my python functions starting the emulators and then executing the starting the function manually. However for this to work I need to provide credentials, and then the function targets the production services instead of the emulator. Anyone knows a way of doing initialize_app forcing it to point to the firestore emulator?

pamafe1976 avatar Apr 08 '24 23:04 pamafe1976

As a workaround, I tried to debug my python functions starting the emulators and then executing the starting the function manually. However for this to work I need to provide credentials, and then the function targets the production services instead of the emulator. Anyone knows a way of doing initialize_app forcing it to point to the firestore emulator?

Have you tried setting these env variables?

process.env.FIREBASE_AUTH_EMULATOR_HOST = '127.0.0.1:9099';
process.env.FIRESTORE_EMULATOR_HOST = '127.0.0.1:8080';

johnnyoshika avatar Apr 09 '24 00:04 johnnyoshika

Thanks @johnnyoshika. That solution worked

As a workaround to debug a Firebase Cloud function in Python, with breakpoint and all, I added this code to my main.py


InitLocalDebug()

initialize_app()

callToTheFunctionYouWantToDebug()

where:

def InitLocalDebug() -> None:
    DIRNAME = os.path.dirname(__file__)
    BASEDIR = os.path.abspath(os.path.join(DIRNAME, '..'))
    GOOGLE_APPLICATION_CREDENTIALS = os.path.join(BASEDIR, 'credentials',
                                                  'firebase_adminsdk_credentials.json')
    os.environ["GOOGLE_APPLICATION_CREDENTIALS"] = GOOGLE_APPLICATION_CREDENTIALS
    os.environ["FIREBASE_AUTH_EMULATOR_HOST"] = "127.0.0.1:9099"
    os.environ["FIRESTORE_EMULATOR_HOST"] = "127.0.0.1:8080"
   # this allows to use StringParam, IntParam, etc normally
    load_dotenv(os.path.join(DIRNAME, '.env.local'))

First I start the all the emulators:

firebase emulators:start --only auth,firestore

And then I run the main.py in debug mode directly from VSCode

pamafe1976 avatar Apr 09 '24 15:04 pamafe1976

@pamafe1976 Thank you! I'll give that a try the next time I need to debug these functions.

johnnyoshika avatar Apr 09 '24 23:04 johnnyoshika

@pamafe1976 so the main.py is like a custom one that you have to test these functions, or it is the typical where you declare all the endpoints (@https_fn.on_request ...)?

Chezlui avatar May 01 '24 18:05 Chezlui

Its actually the same main.py

At the beginning I have a global variable

RUN_LOCAL = False

and the body of the main is something like this:

def InitLocalDebug() -> None:
    DIRNAME = os.path.dirname(__file__)
    BASEDIR = os.path.abspath(os.path.join(DIRNAME, ".."))
    GOOGLE_APPLICATION_CREDENTIALS = os.path.join(
        BASEDIR,
        "credentials",
        "credential_file.json",
    )
    os.environ["GOOGLE_APPLICATION_CREDENTIALS"] = GOOGLE_APPLICATION_CREDENTIALS
    os.environ["FIREBASE_AUTH_EMULATOR_HOST"] = "192.168.1.93:9099"
    os.environ["FIRESTORE_EMULATOR_HOST"] = "192.168.1.93:8080"
    load_dotenv(os.path.join(DIRNAME, ".env.local"))

if RUN_LOCAL:
    InitLocalDebug()

initialize_app()

if RUN_LOCAL:
    requestLocations("")

So when I set RUN_LOCAL=True, I can debug locally the function that is called (in this case requestLocations) And if I set RUN_LOCAL=False, I can either deploy or run with local emulator

pamafe1976 avatar May 02 '24 02:05 pamafe1976

@aalej to be honest is pretty annoying.

I don't understand why there are so few resources related to Python environments compared to JS when both platforms are supposed to be supported in Firebase Functions.

Something fails silently and you spend hours adding traces everywhere when debugging you would find it in a matter of minutes.

Are we just 5 people using Python here?

Chezlui avatar May 08 '24 22:05 Chezlui

I guess it may because Python support started with 2nd gen

pamafe1976 avatar May 08 '24 23:05 pamafe1976

@pamafe1976 I forgot, thank you very much for the tip. Right now it doesn't work for me, because most of my problems are in the middle of sequences of requests and responses of different functions, so using just one doesn't help me a lot.

But it's really helpful though and I will use it for sure.

Chezlui avatar May 08 '24 23:05 Chezlui