Skip to content

FR: Custom headers for httpsCallable #1539

Open
@jjosef

Description

@jjosef

[REQUIRED] Describe your environment

  • Operating System version: macOS 10.14.3
  • Browser version: Chrome 72.0.3626.96
  • Firebase SDK version: 5.8.2
  • Firebase Product: functions

[REQUIRED] Describe the problem

The built in httpsCallable is quite convenient but super limited. Is there a proposal process for expanding this? I would be happy to build the JS spec and possibly other libraries as well.

Adding in the ability to make other request types (GET, PUT, DELETE, etc) would be nice as well. Or is the general consensus to just implement your own if you need that level of flexibility? If so I'd like it if this was documented/easily exported somehow:

  _url(name: string): string {
    const projectId = this.app_.options.projectId;
    const region = this.region_;
    if (this.emulatorOrigin !== null) {
      const origin = this.emulatorOrigin;
      return `${origin}/${projectId}/${region}/${name}`;
    }
    return `https://${region}-${projectId}.cloudfunctions.net/${name}`;
  }

Relevant Code:

packages/functions/src/api/service.ts

simple changes would make this possible:

  private async call(name: string, data: any, defaultHeaders: any): Promise<HttpsCallableResult> {
    const url = this._url(name);

    // Encode any special types, such as dates, in the input data.
    data = this.serializer.encode(data);
    const body = { data };

    // Add a header for the authToken.
    const headers = new Headers(defaultHeaders);
    const context = await this.contextProvider.getContext();
    if (context.authToken) {
      headers.append('Authorization', 'Bearer ' + context.authToken);
    }
    if (context.instanceIdToken) {
      headers.append('Firebase-Instance-ID-Token', context.instanceIdToken);
    }

    const response = await this.postJSON(url, body, headers);

    // Check for an error status, regardless of http status.
    const error = _errorForResponse(
      response.status,
      response.json,
      this.serializer
    );
    if (error) {
      throw error;
    }

    if (!response.json) {
      throw new HttpsErrorImpl(
        'internal',
        'Response is not valid JSON object.'
      );
    }

    let responseData = response.json.data;
    // TODO(klimt): For right now, allow "result" instead of "data", for
    // backwards compatibility.
    if (typeof responseData === 'undefined') {
      responseData = response.json.result;
    }
    if (typeof responseData === 'undefined') {
      // Consider the response malformed.
      throw new HttpsErrorImpl('internal', 'Response is missing data field.');
    }

    // Decode any special types, such as dates, in the returned data.
    const decodedData = this.serializer.decode(responseData);

    return { data: decodedData };
  }

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions