messaging-api-request-internal.js 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  1. /*! firebase-admin v12.1.1 */
  2. "use strict";
  3. /*!
  4. * @license
  5. * Copyright 2017 Google Inc.
  6. *
  7. * Licensed under the Apache License, Version 2.0 (the "License");
  8. * you may not use this file except in compliance with the License.
  9. * You may obtain a copy of the License at
  10. *
  11. * http://www.apache.org/licenses/LICENSE-2.0
  12. *
  13. * Unless required by applicable law or agreed to in writing, software
  14. * distributed under the License is distributed on an "AS IS" BASIS,
  15. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  16. * See the License for the specific language governing permissions and
  17. * limitations under the License.
  18. */
  19. Object.defineProperty(exports, "__esModule", { value: true });
  20. exports.FirebaseMessagingRequestHandler = void 0;
  21. const api_request_1 = require("../utils/api-request");
  22. const messaging_errors_internal_1 = require("./messaging-errors-internal");
  23. const batch_request_internal_1 = require("./batch-request-internal");
  24. const index_1 = require("../utils/index");
  25. // FCM backend constants
  26. const FIREBASE_MESSAGING_TIMEOUT = 15000;
  27. const FIREBASE_MESSAGING_BATCH_URL = 'https://fcm.googleapis.com/batch';
  28. const FIREBASE_MESSAGING_HTTP_METHOD = 'POST';
  29. const FIREBASE_MESSAGING_HEADERS = {
  30. 'X-Firebase-Client': `fire-admin-node/${(0, index_1.getSdkVersion)()}`,
  31. };
  32. const LEGACY_FIREBASE_MESSAGING_HEADERS = {
  33. 'X-Firebase-Client': `fire-admin-node/${(0, index_1.getSdkVersion)()}`,
  34. 'access_token_auth': 'true',
  35. };
  36. /**
  37. * Class that provides a mechanism to send requests to the Firebase Cloud Messaging backend.
  38. */
  39. class FirebaseMessagingRequestHandler {
  40. /**
  41. * @param app - The app used to fetch access tokens to sign API requests.
  42. * @constructor
  43. */
  44. constructor(app) {
  45. this.httpClient = new api_request_1.AuthorizedHttpClient(app);
  46. this.batchClient = new batch_request_internal_1.BatchRequestClient(this.httpClient, FIREBASE_MESSAGING_BATCH_URL, FIREBASE_MESSAGING_HEADERS);
  47. }
  48. /**
  49. * Invokes the request handler with the provided request data.
  50. *
  51. * @param host - The host to which to send the request.
  52. * @param path - The path to which to send the request.
  53. * @param requestData - The request data.
  54. * @returns A promise that resolves with the response.
  55. */
  56. invokeRequestHandler(host, path, requestData) {
  57. const request = {
  58. method: FIREBASE_MESSAGING_HTTP_METHOD,
  59. url: `https://${host}${path}`,
  60. data: requestData,
  61. headers: LEGACY_FIREBASE_MESSAGING_HEADERS,
  62. timeout: FIREBASE_MESSAGING_TIMEOUT,
  63. };
  64. return this.httpClient.send(request).then((response) => {
  65. // Send non-JSON responses to the catch() below where they will be treated as errors.
  66. if (!response.isJson()) {
  67. throw new api_request_1.HttpError(response);
  68. }
  69. // Check for backend errors in the response.
  70. const errorCode = (0, messaging_errors_internal_1.getErrorCode)(response.data);
  71. if (errorCode) {
  72. throw new api_request_1.HttpError(response);
  73. }
  74. // Return entire response.
  75. return response.data;
  76. })
  77. .catch((err) => {
  78. if (err instanceof api_request_1.HttpError) {
  79. throw (0, messaging_errors_internal_1.createFirebaseError)(err);
  80. }
  81. // Re-throw the error if it already has the proper format.
  82. throw err;
  83. });
  84. }
  85. /**
  86. * Invokes the request handler with the provided request data.
  87. *
  88. * @param host - The host to which to send the request.
  89. * @param path - The path to which to send the request.
  90. * @param requestData - The request data.
  91. * @returns A promise that resolves with the {@link SendResponse}.
  92. */
  93. invokeRequestHandlerForSendResponse(host, path, requestData) {
  94. const request = {
  95. method: FIREBASE_MESSAGING_HTTP_METHOD,
  96. url: `https://${host}${path}`,
  97. data: requestData,
  98. headers: LEGACY_FIREBASE_MESSAGING_HEADERS,
  99. timeout: FIREBASE_MESSAGING_TIMEOUT,
  100. };
  101. return this.httpClient.send(request).then((response) => {
  102. return this.buildSendResponse(response);
  103. })
  104. .catch((err) => {
  105. if (err instanceof api_request_1.HttpError) {
  106. return this.buildSendResponseFromError(err);
  107. }
  108. // Re-throw the error if it already has the proper format.
  109. throw err;
  110. });
  111. }
  112. /**
  113. * Sends the given array of sub requests as a single batch to FCM, and parses the result into
  114. * a BatchResponse object.
  115. *
  116. * @param requests - An array of sub requests to send.
  117. * @returns A promise that resolves when the send operation is complete.
  118. */
  119. sendBatchRequest(requests) {
  120. return this.batchClient.send(requests)
  121. .then((responses) => {
  122. return responses.map((part) => {
  123. return this.buildSendResponse(part);
  124. });
  125. }).then((responses) => {
  126. const successCount = responses.filter((resp) => resp.success).length;
  127. return {
  128. responses,
  129. successCount,
  130. failureCount: responses.length - successCount,
  131. };
  132. }).catch((err) => {
  133. if (err instanceof api_request_1.HttpError) {
  134. throw (0, messaging_errors_internal_1.createFirebaseError)(err);
  135. }
  136. // Re-throw the error if it already has the proper format.
  137. throw err;
  138. });
  139. }
  140. buildSendResponse(response) {
  141. const result = {
  142. success: response.status === 200,
  143. };
  144. if (result.success) {
  145. result.messageId = response.data.name;
  146. }
  147. else {
  148. result.error = (0, messaging_errors_internal_1.createFirebaseError)(new api_request_1.HttpError(response));
  149. }
  150. return result;
  151. }
  152. buildSendResponseFromError(err) {
  153. return {
  154. success: false,
  155. error: (0, messaging_errors_internal_1.createFirebaseError)(err)
  156. };
  157. }
  158. }
  159. exports.FirebaseMessagingRequestHandler = FirebaseMessagingRequestHandler;