Skip to content

Make this work in Firebase Studio #1077

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

Open
wants to merge 17 commits into
base: master
Choose a base branch
from
Open

Make this work in Firebase Studio #1077

wants to merge 17 commits into from

Conversation

joehan
Copy link
Contributor

@joehan joehan commented Apr 22, 2025

Bunch of changes to get the emulator UI working in Firebase Studio:

  • Updates the SDK version to pick up required changes. (TODO: move this from release tag to real version before merge)
  • Adds a wrapper around fetch so we can always send credentials if needed
  • Preload cookies with a GET call to all .cloudworkstations.dev hosts
  • Get rid of some wonky logic that was forcing firestore websocket host to be the same as the http host.

While we're here, also doing some overdue maintainence:

  • Update min node version to match the rest of the Firebase world
  • Update CI to use modern versions of node

@joehan joehan changed the title Starting to make this work in Studio Make this work in Firebase Studio May 1, 2025
@@ -53,3 +55,7 @@ export function useRequest<T = unknown>(
refreshWhenOffline: true,
});
}

function isCloudWorkstation(url: string) {
return url.includes('cloudworkstations.dev');
Copy link

Choose a reason for hiding this comment

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

I think this should be .endsWith

Suggested change
return url.includes('cloudworkstations.dev');
return url.endsWith('.cloudworkstations.dev');

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Nope, url can include paths - ie: '9099-blah.cluster.cloudworkstations.dev/auth'

Copy link

Choose a reason for hiding this comment

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

nit: I think my preference is that we call this with the hostname path if we have it and therefore have endsWith just so that it's a stronger validation

const loadCloudWorkstationCookies = async (url?: string) => {
if (url && url.includes('cloudworkstations.dev')) {
try {
const res = await fetchMaybeWithCredentials(url);
Copy link

Choose a reason for hiding this comment

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

Something I'm considering down the line is exponential backoff for the situation when the user hasn't started the emulator yet

package.json Outdated
@@ -42,7 +42,7 @@
"classnames": "^2.2.6",
"codemirror": "^5.61.1",
"express": "^4.17.1",
"firebase": "^10.7.1",
"firebase": "^11.6.1-firebase-studio-sdk-integration.226be0bb1",
Copy link

Choose a reason for hiding this comment

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

Are we merging this for an official release?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

No, we'll wait for the real release - adding a note to the descriptio n

result[key as Emulator] = {
...value,
host,
port,
hostAndPort: hostAndPort(host, port),
};
}

if (result.firestore?.webSocketPort) {
Copy link

Choose a reason for hiding this comment

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

previously you only remapped the webSocketPort if it was set, do you need to preserve this if statement?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I think it's likely irrelevant (webSocketPort is always provided), but added it back in

Copy link

Choose a reason for hiding this comment

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

Did you mean to bring this back?

@@ -115,3 +115,23 @@ function toFormData(file: File) {
formData.append('upload', file);
return formData;
}

function isCloudWorkstation(url: string) {
return url.includes('cloudworkstations.dev');
Copy link

Choose a reason for hiding this comment

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

let's prepend with a "." so we don't accidentally catch other domains that just happen to end in this string, see @maneesht comment in the other implementation of this

opts = {};
}
if (isCloudWorkstation(url)) {
opts.credentials = 'include';
Copy link
Member

Choose a reason for hiding this comment

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

I think you can just do

Suggested change
opts.credentials = 'include';
opts = {...opts, credentials: 'include'};

It will handle undefined without Line 130-132 and it avoids modifying the argument

src/firebase.ts Outdated
const [app, setApp] = useState<FirebaseApp | undefined>();

void Promise.all([
Copy link
Member

Choose a reason for hiding this comment

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

nit: I think you can just void each without Promise.all

@joehan joehan enabled auto-merge (squash) May 7, 2025 18:50
@joehan joehan disabled auto-merge May 7, 2025 20:06
@joehan joehan enabled auto-merge (squash) May 7, 2025 20:06
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.

4 participants