Skip to content

fix(emulator): display localhost in function initialization URLs (Fix issue 3728) - #10904

Open
aanyabharti101 wants to merge 2 commits into
firebase:mainfrom
aanyabharti101:fix-issue-3728
Open

fix(emulator): display localhost in function initialization URLs (Fix issue 3728)#10904
aanyabharti101 wants to merge 2 commits into
firebase:mainfrom
aanyabharti101:fix-issue-3728

Conversation

@aanyabharti101

Copy link
Copy Markdown

Description

Fixes #3728.

Function initialization messages can display local URLs using 0.0.0.0 or 127.0.0.1, which is inconvenient because developers generally expect a browser-friendly localhost URL.

This change adds display-only URL formatting that replaces those local IPv4 addresses with localhost. Non-loopback hosts remain unchanged, and the emulator's internal binding and networking behavior are not affected.

Before:

http://0.0.0.0:9002/...
http://127.0.0.1:9002/...

After:

http://localhost:9002/...

Scenarios Tested

  • Confirmed that 0.0.0.0 is displayed as localhost.
  • Confirmed that 127.0.0.1 is displayed as localhost.
  • Confirmed that non-loopback hosts remain unchanged.
  • Ran the complete related utility test file with all 28 tests passing.
  • Ran the changed-file lint check with 0 errors.
  • Built the complete Firebase Tools CLI successfully.
  • Launched the Functions Emulator and confirmed that initialization URLs display http://localhost:9002/....

Acceptance Criteria

  • Tests added for the new behavior
  • All directly related tests passing
  • Follows the project style requirements
  • No unrelated or breaking changes introduced
  • Documentation changes are not required

Sample Commands

node lib/bin/firebase.js emulators:start \
  --config scripts/triggers-end-to-end-tests/firebase.json \
  --only functions:v1 \
  --project demo-test

@google-cla

google-cla Bot commented Aug 7, 2026

Copy link
Copy Markdown

Thanks for your pull request! It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA).

View this failed invocation of the CLA check for more information.

For the most up to date status, view the checks section at the bottom of the pull request.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a utility function formatFunctionUrlForDisplay to format function URLs for display by replacing IPv4 wildcard (0.0.0.0) and loopback (127.0.0.1) hostnames with localhost, and integrates it into the functions emulator logs along with corresponding unit tests. The feedback suggests enhancing this utility's robustness by wrapping the URL parsing in a try...catch block to handle invalid URLs gracefully, extending support to IPv6 loopback addresses (::1 and [::1]), and adding unit tests to cover these scenarios.

Comment on lines +14 to +22
export function formatFunctionUrlForDisplay(url: string): string {
const parsedUrl = new URL(url);

if (parsedUrl.hostname === "0.0.0.0" || parsedUrl.hostname === "127.0.0.1") {
parsedUrl.hostname = "localhost";
}

return parsedUrl.toString();
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

To make this utility more robust and complete, consider the following improvements:\n\n1. Defensive Programming: new URL(url) throws a TypeError if the input is not a valid absolute URL. Wrapping this in a try...catch block and falling back to the original url prevents potential runtime crashes.\n2. IPv6 Support: The current check only covers IPv4 (127.0.0.1 and 0.0.0.0). Adding support for IPv6 loopback ([::1] and ::1) ensures consistency with other localhost utilities in this file (like isLocalHost).

Suggested change
export function formatFunctionUrlForDisplay(url: string): string {
const parsedUrl = new URL(url);
if (parsedUrl.hostname === "0.0.0.0" || parsedUrl.hostname === "127.0.0.1") {
parsedUrl.hostname = "localhost";
}
return parsedUrl.toString();
}
export function formatFunctionUrlForDisplay(url: string): string {
try {
const parsedUrl = new URL(url);
if (
parsedUrl.hostname === "0.0.0.0" ||
parsedUrl.hostname === "127.0.0.1" ||
parsedUrl.hostname === "::1" ||
parsedUrl.hostname === "[::1]"
) {
parsedUrl.hostname = "localhost";
}
return parsedUrl.toString();
} catch {
return url;
}
}

Comment on lines +205 to +209
it("should preserve non-loopback hosts", () => {
const url = "http://192.168.1.10:5001/demo-project/us-central1/testFunction";

expect(formatFunctionUrlForDisplay(url)).to.equal(url);
});

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Add unit tests to verify the behavior of formatFunctionUrlForDisplay with IPv6 loopback addresses and invalid URL strings, matching the defensive programming and IPv6 improvements.

    it("should preserve non-loopback hosts", () => {
      const url = "http://192.168.1.10:5001/demo-project/us-central1/testFunction";

      expect(formatFunctionUrlForDisplay(url)).to.equal(url);
    });

    it("should display localhost instead of the IPv6 loopback address", () => {
      const url = "http://[::1]:5001/demo-project/us-central1/testFunction";

      expect(formatFunctionUrlForDisplay(url)).to.equal(
        "http://localhost:5001/demo-project/us-central1/testFunction",
      );
    });

    it("should gracefully handle and return invalid URLs", () => {
      const url = "invalid-url-string";

      expect(formatFunctionUrlForDisplay(url)).to.equal(url);
    });

@aanyabharti101

Copy link
Copy Markdown
Author

Hi @yuchenshi and @joehan, I’ve opened this PR to address #3728. When you have a chance, I’d appreciate your review. Thank you!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Display proper URLs when initializing.

2 participants