@firebase/messaging 0.12.12 → 0.12.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/esm/index.esm2017.js +2 -2
- package/dist/esm/index.esm2017.js.map +1 -1
- package/dist/esm/index.sw.esm2017.js.map +1 -1
- package/dist/index.cjs.js +482 -779
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.sw.cjs +488 -804
- package/dist/index.sw.cjs.map +1 -1
- package/package.json +5 -7
- package/dist/esm/index.esm.js +0 -1530
- package/dist/esm/index.esm.js.map +0 -1
package/dist/index.sw.cjs
CHANGED
|
@@ -4,7 +4,6 @@ Object.defineProperty(exports, '__esModule', { value: true });
|
|
|
4
4
|
|
|
5
5
|
require('@firebase/installations');
|
|
6
6
|
var component = require('@firebase/component');
|
|
7
|
-
var tslib = require('tslib');
|
|
8
7
|
var idb = require('idb');
|
|
9
8
|
var util = require('@firebase/util');
|
|
10
9
|
var app = require('@firebase/app');
|
|
@@ -25,14 +24,14 @@ var app = require('@firebase/app');
|
|
|
25
24
|
* See the License for the specific language governing permissions and
|
|
26
25
|
* limitations under the License.
|
|
27
26
|
*/
|
|
28
|
-
|
|
29
|
-
|
|
27
|
+
const DEFAULT_VAPID_KEY = 'BDOU99-h67HcA6JeFXHbSNMu7e2yNNu3RzoMj8TM4W88jITfq7ZmPvIM1Iv-4_l2LxQcYwhqby2xGpWwzjfAnG4';
|
|
28
|
+
const ENDPOINT = 'https://fcmregistrations.googleapis.com/v1';
|
|
30
29
|
/** Key of FCM Payload in Notification's data field. */
|
|
31
|
-
|
|
32
|
-
|
|
30
|
+
const FCM_MSG = 'FCM_MSG';
|
|
31
|
+
const CONSOLE_CAMPAIGN_ID = 'google.c.a.c_id';
|
|
33
32
|
// Defined as in proto/messaging_event.proto. Neglecting fields that are supported.
|
|
34
|
-
|
|
35
|
-
|
|
33
|
+
const SDK_PLATFORM_WEB = 3;
|
|
34
|
+
const EVENT_MESSAGE_DELIVERED = 1;
|
|
36
35
|
var MessageType$1;
|
|
37
36
|
(function (MessageType) {
|
|
38
37
|
MessageType[MessageType["DATA_MESSAGE"] = 1] = "DATA_MESSAGE";
|
|
@@ -76,18 +75,18 @@ var MessageType;
|
|
|
76
75
|
* limitations under the License.
|
|
77
76
|
*/
|
|
78
77
|
function arrayToBase64(array) {
|
|
79
|
-
|
|
80
|
-
|
|
78
|
+
const uint8Array = new Uint8Array(array);
|
|
79
|
+
const base64String = btoa(String.fromCharCode(...uint8Array));
|
|
81
80
|
return base64String.replace(/=/g, '').replace(/\+/g, '-').replace(/\//g, '_');
|
|
82
81
|
}
|
|
83
82
|
function base64ToArray(base64String) {
|
|
84
|
-
|
|
85
|
-
|
|
83
|
+
const padding = '='.repeat((4 - (base64String.length % 4)) % 4);
|
|
84
|
+
const base64 = (base64String + padding)
|
|
86
85
|
.replace(/\-/g, '+')
|
|
87
86
|
.replace(/_/g, '/');
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
for (
|
|
87
|
+
const rawData = atob(base64);
|
|
88
|
+
const outputArray = new Uint8Array(rawData.length);
|
|
89
|
+
for (let i = 0; i < rawData.length; ++i) {
|
|
91
90
|
outputArray[i] = rawData.charCodeAt(i);
|
|
92
91
|
}
|
|
93
92
|
return outputArray;
|
|
@@ -109,134 +108,104 @@ function base64ToArray(base64String) {
|
|
|
109
108
|
* See the License for the specific language governing permissions and
|
|
110
109
|
* limitations under the License.
|
|
111
110
|
*/
|
|
112
|
-
|
|
111
|
+
const OLD_DB_NAME = 'fcm_token_details_db';
|
|
113
112
|
/**
|
|
114
113
|
* The last DB version of 'fcm_token_details_db' was 4. This is one higher, so that the upgrade
|
|
115
114
|
* callback is called for all versions of the old DB.
|
|
116
115
|
*/
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
function migrateOldDatabase(senderId) {
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
116
|
+
const OLD_DB_VERSION = 5;
|
|
117
|
+
const OLD_OBJECT_STORE_NAME = 'fcm_token_object_Store';
|
|
118
|
+
async function migrateOldDatabase(senderId) {
|
|
119
|
+
if ('databases' in indexedDB) {
|
|
120
|
+
// indexedDb.databases() is an IndexedDB v3 API and does not exist in all browsers. TODO: Remove
|
|
121
|
+
// typecast when it lands in TS types.
|
|
122
|
+
const databases = await indexedDB.databases();
|
|
123
|
+
const dbNames = databases.map(db => db.name);
|
|
124
|
+
if (!dbNames.includes(OLD_DB_NAME)) {
|
|
125
|
+
// old DB didn't exist, no need to open.
|
|
126
|
+
return null;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
let tokenDetails = null;
|
|
130
|
+
const db = await idb.openDB(OLD_DB_NAME, OLD_DB_VERSION, {
|
|
131
|
+
upgrade: async (db, oldVersion, newVersion, upgradeTransaction) => {
|
|
132
|
+
var _a;
|
|
133
|
+
if (oldVersion < 2) {
|
|
134
|
+
// Database too old, skip migration.
|
|
135
|
+
return;
|
|
136
|
+
}
|
|
137
|
+
if (!db.objectStoreNames.contains(OLD_OBJECT_STORE_NAME)) {
|
|
138
|
+
// Database did not exist. Nothing to do.
|
|
139
|
+
return;
|
|
140
|
+
}
|
|
141
|
+
const objectStore = upgradeTransaction.objectStore(OLD_OBJECT_STORE_NAME);
|
|
142
|
+
const value = await objectStore.index('fcmSenderId').get(senderId);
|
|
143
|
+
await objectStore.clear();
|
|
144
|
+
if (!value) {
|
|
145
|
+
// No entry in the database, nothing to migrate.
|
|
146
|
+
return;
|
|
147
|
+
}
|
|
148
|
+
if (oldVersion === 2) {
|
|
149
|
+
const oldDetails = value;
|
|
150
|
+
if (!oldDetails.auth || !oldDetails.p256dh || !oldDetails.endpoint) {
|
|
151
|
+
return;
|
|
152
|
+
}
|
|
153
|
+
tokenDetails = {
|
|
154
|
+
token: oldDetails.fcmToken,
|
|
155
|
+
createTime: (_a = oldDetails.createTime) !== null && _a !== void 0 ? _a : Date.now(),
|
|
156
|
+
subscriptionOptions: {
|
|
157
|
+
auth: oldDetails.auth,
|
|
158
|
+
p256dh: oldDetails.p256dh,
|
|
159
|
+
endpoint: oldDetails.endpoint,
|
|
160
|
+
swScope: oldDetails.swScope,
|
|
161
|
+
vapidKey: typeof oldDetails.vapidKey === 'string'
|
|
162
|
+
? oldDetails.vapidKey
|
|
163
|
+
: arrayToBase64(oldDetails.vapidKey)
|
|
134
164
|
}
|
|
135
|
-
|
|
136
|
-
case 2:
|
|
137
|
-
tokenDetails = null;
|
|
138
|
-
return [4 /*yield*/, idb.openDB(OLD_DB_NAME, OLD_DB_VERSION, {
|
|
139
|
-
upgrade: function (db, oldVersion, newVersion, upgradeTransaction) { return tslib.__awaiter(_this, void 0, void 0, function () {
|
|
140
|
-
var objectStore, value, oldDetails, oldDetails, oldDetails;
|
|
141
|
-
var _a;
|
|
142
|
-
return tslib.__generator(this, function (_b) {
|
|
143
|
-
switch (_b.label) {
|
|
144
|
-
case 0:
|
|
145
|
-
if (oldVersion < 2) {
|
|
146
|
-
// Database too old, skip migration.
|
|
147
|
-
return [2 /*return*/];
|
|
148
|
-
}
|
|
149
|
-
if (!db.objectStoreNames.contains(OLD_OBJECT_STORE_NAME)) {
|
|
150
|
-
// Database did not exist. Nothing to do.
|
|
151
|
-
return [2 /*return*/];
|
|
152
|
-
}
|
|
153
|
-
objectStore = upgradeTransaction.objectStore(OLD_OBJECT_STORE_NAME);
|
|
154
|
-
return [4 /*yield*/, objectStore.index('fcmSenderId').get(senderId)];
|
|
155
|
-
case 1:
|
|
156
|
-
value = _b.sent();
|
|
157
|
-
return [4 /*yield*/, objectStore.clear()];
|
|
158
|
-
case 2:
|
|
159
|
-
_b.sent();
|
|
160
|
-
if (!value) {
|
|
161
|
-
// No entry in the database, nothing to migrate.
|
|
162
|
-
return [2 /*return*/];
|
|
163
|
-
}
|
|
164
|
-
if (oldVersion === 2) {
|
|
165
|
-
oldDetails = value;
|
|
166
|
-
if (!oldDetails.auth || !oldDetails.p256dh || !oldDetails.endpoint) {
|
|
167
|
-
return [2 /*return*/];
|
|
168
|
-
}
|
|
169
|
-
tokenDetails = {
|
|
170
|
-
token: oldDetails.fcmToken,
|
|
171
|
-
createTime: (_a = oldDetails.createTime) !== null && _a !== void 0 ? _a : Date.now(),
|
|
172
|
-
subscriptionOptions: {
|
|
173
|
-
auth: oldDetails.auth,
|
|
174
|
-
p256dh: oldDetails.p256dh,
|
|
175
|
-
endpoint: oldDetails.endpoint,
|
|
176
|
-
swScope: oldDetails.swScope,
|
|
177
|
-
vapidKey: typeof oldDetails.vapidKey === 'string'
|
|
178
|
-
? oldDetails.vapidKey
|
|
179
|
-
: arrayToBase64(oldDetails.vapidKey)
|
|
180
|
-
}
|
|
181
|
-
};
|
|
182
|
-
}
|
|
183
|
-
else if (oldVersion === 3) {
|
|
184
|
-
oldDetails = value;
|
|
185
|
-
tokenDetails = {
|
|
186
|
-
token: oldDetails.fcmToken,
|
|
187
|
-
createTime: oldDetails.createTime,
|
|
188
|
-
subscriptionOptions: {
|
|
189
|
-
auth: arrayToBase64(oldDetails.auth),
|
|
190
|
-
p256dh: arrayToBase64(oldDetails.p256dh),
|
|
191
|
-
endpoint: oldDetails.endpoint,
|
|
192
|
-
swScope: oldDetails.swScope,
|
|
193
|
-
vapidKey: arrayToBase64(oldDetails.vapidKey)
|
|
194
|
-
}
|
|
195
|
-
};
|
|
196
|
-
}
|
|
197
|
-
else if (oldVersion === 4) {
|
|
198
|
-
oldDetails = value;
|
|
199
|
-
tokenDetails = {
|
|
200
|
-
token: oldDetails.fcmToken,
|
|
201
|
-
createTime: oldDetails.createTime,
|
|
202
|
-
subscriptionOptions: {
|
|
203
|
-
auth: arrayToBase64(oldDetails.auth),
|
|
204
|
-
p256dh: arrayToBase64(oldDetails.p256dh),
|
|
205
|
-
endpoint: oldDetails.endpoint,
|
|
206
|
-
swScope: oldDetails.swScope,
|
|
207
|
-
vapidKey: arrayToBase64(oldDetails.vapidKey)
|
|
208
|
-
}
|
|
209
|
-
};
|
|
210
|
-
}
|
|
211
|
-
return [2 /*return*/];
|
|
212
|
-
}
|
|
213
|
-
});
|
|
214
|
-
}); }
|
|
215
|
-
})];
|
|
216
|
-
case 3:
|
|
217
|
-
db = _a.sent();
|
|
218
|
-
db.close();
|
|
219
|
-
// Delete all old databases.
|
|
220
|
-
return [4 /*yield*/, idb.deleteDB(OLD_DB_NAME)];
|
|
221
|
-
case 4:
|
|
222
|
-
// Delete all old databases.
|
|
223
|
-
_a.sent();
|
|
224
|
-
return [4 /*yield*/, idb.deleteDB('fcm_vapid_details_db')];
|
|
225
|
-
case 5:
|
|
226
|
-
_a.sent();
|
|
227
|
-
return [4 /*yield*/, idb.deleteDB('undefined')];
|
|
228
|
-
case 6:
|
|
229
|
-
_a.sent();
|
|
230
|
-
return [2 /*return*/, checkTokenDetails(tokenDetails) ? tokenDetails : null];
|
|
165
|
+
};
|
|
231
166
|
}
|
|
232
|
-
|
|
167
|
+
else if (oldVersion === 3) {
|
|
168
|
+
const oldDetails = value;
|
|
169
|
+
tokenDetails = {
|
|
170
|
+
token: oldDetails.fcmToken,
|
|
171
|
+
createTime: oldDetails.createTime,
|
|
172
|
+
subscriptionOptions: {
|
|
173
|
+
auth: arrayToBase64(oldDetails.auth),
|
|
174
|
+
p256dh: arrayToBase64(oldDetails.p256dh),
|
|
175
|
+
endpoint: oldDetails.endpoint,
|
|
176
|
+
swScope: oldDetails.swScope,
|
|
177
|
+
vapidKey: arrayToBase64(oldDetails.vapidKey)
|
|
178
|
+
}
|
|
179
|
+
};
|
|
180
|
+
}
|
|
181
|
+
else if (oldVersion === 4) {
|
|
182
|
+
const oldDetails = value;
|
|
183
|
+
tokenDetails = {
|
|
184
|
+
token: oldDetails.fcmToken,
|
|
185
|
+
createTime: oldDetails.createTime,
|
|
186
|
+
subscriptionOptions: {
|
|
187
|
+
auth: arrayToBase64(oldDetails.auth),
|
|
188
|
+
p256dh: arrayToBase64(oldDetails.p256dh),
|
|
189
|
+
endpoint: oldDetails.endpoint,
|
|
190
|
+
swScope: oldDetails.swScope,
|
|
191
|
+
vapidKey: arrayToBase64(oldDetails.vapidKey)
|
|
192
|
+
}
|
|
193
|
+
};
|
|
194
|
+
}
|
|
195
|
+
}
|
|
233
196
|
});
|
|
197
|
+
db.close();
|
|
198
|
+
// Delete all old databases.
|
|
199
|
+
await idb.deleteDB(OLD_DB_NAME);
|
|
200
|
+
await idb.deleteDB('fcm_vapid_details_db');
|
|
201
|
+
await idb.deleteDB('undefined');
|
|
202
|
+
return checkTokenDetails(tokenDetails) ? tokenDetails : null;
|
|
234
203
|
}
|
|
235
204
|
function checkTokenDetails(tokenDetails) {
|
|
236
205
|
if (!tokenDetails || !tokenDetails.subscriptionOptions) {
|
|
237
206
|
return false;
|
|
238
207
|
}
|
|
239
|
-
|
|
208
|
+
const { subscriptionOptions } = tokenDetails;
|
|
240
209
|
return (typeof tokenDetails.createTime === 'number' &&
|
|
241
210
|
tokenDetails.createTime > 0 &&
|
|
242
211
|
typeof tokenDetails.token === 'string' &&
|
|
@@ -270,14 +239,14 @@ function checkTokenDetails(tokenDetails) {
|
|
|
270
239
|
* limitations under the License.
|
|
271
240
|
*/
|
|
272
241
|
// Exported for tests.
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
242
|
+
const DATABASE_NAME = 'firebase-messaging-database';
|
|
243
|
+
const DATABASE_VERSION = 1;
|
|
244
|
+
const OBJECT_STORE_NAME = 'firebase-messaging-store';
|
|
245
|
+
let dbPromise = null;
|
|
277
246
|
function getDbPromise() {
|
|
278
247
|
if (!dbPromise) {
|
|
279
248
|
dbPromise = idb.openDB(DATABASE_NAME, DATABASE_VERSION, {
|
|
280
|
-
upgrade:
|
|
249
|
+
upgrade: (upgradeDb, oldVersion) => {
|
|
281
250
|
// We don't use 'break' in this switch statement, the fall-through behavior is what we want,
|
|
282
251
|
// because if there are multiple versions between the old version and the current version, we
|
|
283
252
|
// want ALL the migrations that correspond to those versions to run, not only the last one.
|
|
@@ -292,85 +261,43 @@ function getDbPromise() {
|
|
|
292
261
|
return dbPromise;
|
|
293
262
|
}
|
|
294
263
|
/** Gets record(s) from the objectStore that match the given key. */
|
|
295
|
-
function dbGet(firebaseDependencies) {
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
case 3: return [4 /*yield*/, migrateOldDatabase(firebaseDependencies.appConfig.senderId)];
|
|
314
|
-
case 4:
|
|
315
|
-
oldTokenDetails = _a.sent();
|
|
316
|
-
if (!oldTokenDetails) return [3 /*break*/, 6];
|
|
317
|
-
return [4 /*yield*/, dbSet(firebaseDependencies, oldTokenDetails)];
|
|
318
|
-
case 5:
|
|
319
|
-
_a.sent();
|
|
320
|
-
return [2 /*return*/, oldTokenDetails];
|
|
321
|
-
case 6: return [2 /*return*/];
|
|
322
|
-
}
|
|
323
|
-
});
|
|
324
|
-
});
|
|
264
|
+
async function dbGet(firebaseDependencies) {
|
|
265
|
+
const key = getKey(firebaseDependencies);
|
|
266
|
+
const db = await getDbPromise();
|
|
267
|
+
const tokenDetails = (await db
|
|
268
|
+
.transaction(OBJECT_STORE_NAME)
|
|
269
|
+
.objectStore(OBJECT_STORE_NAME)
|
|
270
|
+
.get(key));
|
|
271
|
+
if (tokenDetails) {
|
|
272
|
+
return tokenDetails;
|
|
273
|
+
}
|
|
274
|
+
else {
|
|
275
|
+
// Check if there is a tokenDetails object in the old DB.
|
|
276
|
+
const oldTokenDetails = await migrateOldDatabase(firebaseDependencies.appConfig.senderId);
|
|
277
|
+
if (oldTokenDetails) {
|
|
278
|
+
await dbSet(firebaseDependencies, oldTokenDetails);
|
|
279
|
+
return oldTokenDetails;
|
|
280
|
+
}
|
|
281
|
+
}
|
|
325
282
|
}
|
|
326
283
|
/** Assigns or overwrites the record for the given key with the given value. */
|
|
327
|
-
function dbSet(firebaseDependencies, tokenDetails) {
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
return [4 /*yield*/, getDbPromise()];
|
|
335
|
-
case 1:
|
|
336
|
-
db = _a.sent();
|
|
337
|
-
tx = db.transaction(OBJECT_STORE_NAME, 'readwrite');
|
|
338
|
-
return [4 /*yield*/, tx.objectStore(OBJECT_STORE_NAME).put(tokenDetails, key)];
|
|
339
|
-
case 2:
|
|
340
|
-
_a.sent();
|
|
341
|
-
return [4 /*yield*/, tx.done];
|
|
342
|
-
case 3:
|
|
343
|
-
_a.sent();
|
|
344
|
-
return [2 /*return*/, tokenDetails];
|
|
345
|
-
}
|
|
346
|
-
});
|
|
347
|
-
});
|
|
284
|
+
async function dbSet(firebaseDependencies, tokenDetails) {
|
|
285
|
+
const key = getKey(firebaseDependencies);
|
|
286
|
+
const db = await getDbPromise();
|
|
287
|
+
const tx = db.transaction(OBJECT_STORE_NAME, 'readwrite');
|
|
288
|
+
await tx.objectStore(OBJECT_STORE_NAME).put(tokenDetails, key);
|
|
289
|
+
await tx.done;
|
|
290
|
+
return tokenDetails;
|
|
348
291
|
}
|
|
349
292
|
/** Removes record(s) from the objectStore that match the given key. */
|
|
350
|
-
function dbRemove(firebaseDependencies) {
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
key = getKey(firebaseDependencies);
|
|
357
|
-
return [4 /*yield*/, getDbPromise()];
|
|
358
|
-
case 1:
|
|
359
|
-
db = _a.sent();
|
|
360
|
-
tx = db.transaction(OBJECT_STORE_NAME, 'readwrite');
|
|
361
|
-
return [4 /*yield*/, tx.objectStore(OBJECT_STORE_NAME).delete(key)];
|
|
362
|
-
case 2:
|
|
363
|
-
_a.sent();
|
|
364
|
-
return [4 /*yield*/, tx.done];
|
|
365
|
-
case 3:
|
|
366
|
-
_a.sent();
|
|
367
|
-
return [2 /*return*/];
|
|
368
|
-
}
|
|
369
|
-
});
|
|
370
|
-
});
|
|
293
|
+
async function dbRemove(firebaseDependencies) {
|
|
294
|
+
const key = getKey(firebaseDependencies);
|
|
295
|
+
const db = await getDbPromise();
|
|
296
|
+
const tx = db.transaction(OBJECT_STORE_NAME, 'readwrite');
|
|
297
|
+
await tx.objectStore(OBJECT_STORE_NAME).delete(key);
|
|
298
|
+
await tx.done;
|
|
371
299
|
}
|
|
372
|
-
function getKey(
|
|
373
|
-
var appConfig = _a.appConfig;
|
|
300
|
+
function getKey({ appConfig }) {
|
|
374
301
|
return appConfig.appId;
|
|
375
302
|
}
|
|
376
303
|
|
|
@@ -390,31 +317,30 @@ function getKey(_a) {
|
|
|
390
317
|
* See the License for the specific language governing permissions and
|
|
391
318
|
* limitations under the License.
|
|
392
319
|
*/
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
_a["token-unsubscribe-failed" /* ErrorCode.TOKEN_UNSUBSCRIBE_FAILED */] = 'A problem occurred while unsubscribing the ' +
|
|
320
|
+
const ERROR_MAP = {
|
|
321
|
+
["missing-app-config-values" /* ErrorCode.MISSING_APP_CONFIG_VALUES */]: 'Missing App configuration value: "{$valueName}"',
|
|
322
|
+
["only-available-in-window" /* ErrorCode.AVAILABLE_IN_WINDOW */]: 'This method is available in a Window context.',
|
|
323
|
+
["only-available-in-sw" /* ErrorCode.AVAILABLE_IN_SW */]: 'This method is available in a service worker context.',
|
|
324
|
+
["permission-default" /* ErrorCode.PERMISSION_DEFAULT */]: 'The notification permission was not granted and dismissed instead.',
|
|
325
|
+
["permission-blocked" /* ErrorCode.PERMISSION_BLOCKED */]: 'The notification permission was not granted and blocked instead.',
|
|
326
|
+
["unsupported-browser" /* ErrorCode.UNSUPPORTED_BROWSER */]: "This browser doesn't support the API's required to use the Firebase SDK.",
|
|
327
|
+
["indexed-db-unsupported" /* ErrorCode.INDEXED_DB_UNSUPPORTED */]: "This browser doesn't support indexedDb.open() (ex. Safari iFrame, Firefox Private Browsing, etc)",
|
|
328
|
+
["failed-service-worker-registration" /* ErrorCode.FAILED_DEFAULT_REGISTRATION */]: 'We are unable to register the default service worker. {$browserErrorMessage}',
|
|
329
|
+
["token-subscribe-failed" /* ErrorCode.TOKEN_SUBSCRIBE_FAILED */]: 'A problem occurred while subscribing the user to FCM: {$errorInfo}',
|
|
330
|
+
["token-subscribe-no-token" /* ErrorCode.TOKEN_SUBSCRIBE_NO_TOKEN */]: 'FCM returned no token when subscribing the user to push.',
|
|
331
|
+
["token-unsubscribe-failed" /* ErrorCode.TOKEN_UNSUBSCRIBE_FAILED */]: 'A problem occurred while unsubscribing the ' +
|
|
406
332
|
'user from FCM: {$errorInfo}',
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
333
|
+
["token-update-failed" /* ErrorCode.TOKEN_UPDATE_FAILED */]: 'A problem occurred while updating the user from FCM: {$errorInfo}',
|
|
334
|
+
["token-update-no-token" /* ErrorCode.TOKEN_UPDATE_NO_TOKEN */]: 'FCM returned no token when updating the user to push.',
|
|
335
|
+
["use-sw-after-get-token" /* ErrorCode.USE_SW_AFTER_GET_TOKEN */]: 'The useServiceWorker() method may only be called once and must be ' +
|
|
410
336
|
'called before calling getToken() to ensure your service worker is used.',
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
'called before calling getToken() to ensure your VAPID key is used.'
|
|
416
|
-
|
|
417
|
-
|
|
337
|
+
["invalid-sw-registration" /* ErrorCode.INVALID_SW_REGISTRATION */]: 'The input to useServiceWorker() must be a ServiceWorkerRegistration.',
|
|
338
|
+
["invalid-bg-handler" /* ErrorCode.INVALID_BG_HANDLER */]: 'The input to setBackgroundMessageHandler() must be a function.',
|
|
339
|
+
["invalid-vapid-key" /* ErrorCode.INVALID_VAPID_KEY */]: 'The public VAPID key must be a string.',
|
|
340
|
+
["use-vapid-key-after-get-token" /* ErrorCode.USE_VAPID_KEY_AFTER_GET_TOKEN */]: 'The usePublicVapidKey() method may only be called once and must be ' +
|
|
341
|
+
'called before calling getToken() to ensure your VAPID key is used.'
|
|
342
|
+
};
|
|
343
|
+
const ERROR_FACTORY = new util.ErrorFactory('messaging', 'Messaging', ERROR_MAP);
|
|
418
344
|
|
|
419
345
|
/**
|
|
420
346
|
* @license
|
|
@@ -432,162 +358,104 @@ var ERROR_FACTORY = new util.ErrorFactory('messaging', 'Messaging', ERROR_MAP);
|
|
|
432
358
|
* See the License for the specific language governing permissions and
|
|
433
359
|
* limitations under the License.
|
|
434
360
|
*/
|
|
435
|
-
function requestGetToken(firebaseDependencies, subscriptionOptions) {
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
_a.trys.push([2, 5, , 6]);
|
|
452
|
-
return [4 /*yield*/, fetch(getEndpoint(firebaseDependencies.appConfig), subscribeOptions)];
|
|
453
|
-
case 3:
|
|
454
|
-
response = _a.sent();
|
|
455
|
-
return [4 /*yield*/, response.json()];
|
|
456
|
-
case 4:
|
|
457
|
-
responseData = _a.sent();
|
|
458
|
-
return [3 /*break*/, 6];
|
|
459
|
-
case 5:
|
|
460
|
-
err_1 = _a.sent();
|
|
461
|
-
throw ERROR_FACTORY.create("token-subscribe-failed" /* ErrorCode.TOKEN_SUBSCRIBE_FAILED */, {
|
|
462
|
-
errorInfo: err_1 === null || err_1 === void 0 ? void 0 : err_1.toString()
|
|
463
|
-
});
|
|
464
|
-
case 6:
|
|
465
|
-
if (responseData.error) {
|
|
466
|
-
message = responseData.error.message;
|
|
467
|
-
throw ERROR_FACTORY.create("token-subscribe-failed" /* ErrorCode.TOKEN_SUBSCRIBE_FAILED */, {
|
|
468
|
-
errorInfo: message
|
|
469
|
-
});
|
|
470
|
-
}
|
|
471
|
-
if (!responseData.token) {
|
|
472
|
-
throw ERROR_FACTORY.create("token-subscribe-no-token" /* ErrorCode.TOKEN_SUBSCRIBE_NO_TOKEN */);
|
|
473
|
-
}
|
|
474
|
-
return [2 /*return*/, responseData.token];
|
|
475
|
-
}
|
|
361
|
+
async function requestGetToken(firebaseDependencies, subscriptionOptions) {
|
|
362
|
+
const headers = await getHeaders(firebaseDependencies);
|
|
363
|
+
const body = getBody(subscriptionOptions);
|
|
364
|
+
const subscribeOptions = {
|
|
365
|
+
method: 'POST',
|
|
366
|
+
headers,
|
|
367
|
+
body: JSON.stringify(body)
|
|
368
|
+
};
|
|
369
|
+
let responseData;
|
|
370
|
+
try {
|
|
371
|
+
const response = await fetch(getEndpoint(firebaseDependencies.appConfig), subscribeOptions);
|
|
372
|
+
responseData = await response.json();
|
|
373
|
+
}
|
|
374
|
+
catch (err) {
|
|
375
|
+
throw ERROR_FACTORY.create("token-subscribe-failed" /* ErrorCode.TOKEN_SUBSCRIBE_FAILED */, {
|
|
376
|
+
errorInfo: err === null || err === void 0 ? void 0 : err.toString()
|
|
476
377
|
});
|
|
477
|
-
}
|
|
378
|
+
}
|
|
379
|
+
if (responseData.error) {
|
|
380
|
+
const message = responseData.error.message;
|
|
381
|
+
throw ERROR_FACTORY.create("token-subscribe-failed" /* ErrorCode.TOKEN_SUBSCRIBE_FAILED */, {
|
|
382
|
+
errorInfo: message
|
|
383
|
+
});
|
|
384
|
+
}
|
|
385
|
+
if (!responseData.token) {
|
|
386
|
+
throw ERROR_FACTORY.create("token-subscribe-no-token" /* ErrorCode.TOKEN_SUBSCRIBE_NO_TOKEN */);
|
|
387
|
+
}
|
|
388
|
+
return responseData.token;
|
|
478
389
|
}
|
|
479
|
-
function requestUpdateToken(firebaseDependencies, tokenDetails) {
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
_a.trys.push([2, 5, , 6]);
|
|
496
|
-
return [4 /*yield*/, fetch("".concat(getEndpoint(firebaseDependencies.appConfig), "/").concat(tokenDetails.token), updateOptions)];
|
|
497
|
-
case 3:
|
|
498
|
-
response = _a.sent();
|
|
499
|
-
return [4 /*yield*/, response.json()];
|
|
500
|
-
case 4:
|
|
501
|
-
responseData = _a.sent();
|
|
502
|
-
return [3 /*break*/, 6];
|
|
503
|
-
case 5:
|
|
504
|
-
err_2 = _a.sent();
|
|
505
|
-
throw ERROR_FACTORY.create("token-update-failed" /* ErrorCode.TOKEN_UPDATE_FAILED */, {
|
|
506
|
-
errorInfo: err_2 === null || err_2 === void 0 ? void 0 : err_2.toString()
|
|
507
|
-
});
|
|
508
|
-
case 6:
|
|
509
|
-
if (responseData.error) {
|
|
510
|
-
message = responseData.error.message;
|
|
511
|
-
throw ERROR_FACTORY.create("token-update-failed" /* ErrorCode.TOKEN_UPDATE_FAILED */, {
|
|
512
|
-
errorInfo: message
|
|
513
|
-
});
|
|
514
|
-
}
|
|
515
|
-
if (!responseData.token) {
|
|
516
|
-
throw ERROR_FACTORY.create("token-update-no-token" /* ErrorCode.TOKEN_UPDATE_NO_TOKEN */);
|
|
517
|
-
}
|
|
518
|
-
return [2 /*return*/, responseData.token];
|
|
519
|
-
}
|
|
390
|
+
async function requestUpdateToken(firebaseDependencies, tokenDetails) {
|
|
391
|
+
const headers = await getHeaders(firebaseDependencies);
|
|
392
|
+
const body = getBody(tokenDetails.subscriptionOptions);
|
|
393
|
+
const updateOptions = {
|
|
394
|
+
method: 'PATCH',
|
|
395
|
+
headers,
|
|
396
|
+
body: JSON.stringify(body)
|
|
397
|
+
};
|
|
398
|
+
let responseData;
|
|
399
|
+
try {
|
|
400
|
+
const response = await fetch(`${getEndpoint(firebaseDependencies.appConfig)}/${tokenDetails.token}`, updateOptions);
|
|
401
|
+
responseData = await response.json();
|
|
402
|
+
}
|
|
403
|
+
catch (err) {
|
|
404
|
+
throw ERROR_FACTORY.create("token-update-failed" /* ErrorCode.TOKEN_UPDATE_FAILED */, {
|
|
405
|
+
errorInfo: err === null || err === void 0 ? void 0 : err.toString()
|
|
520
406
|
});
|
|
521
|
-
}
|
|
407
|
+
}
|
|
408
|
+
if (responseData.error) {
|
|
409
|
+
const message = responseData.error.message;
|
|
410
|
+
throw ERROR_FACTORY.create("token-update-failed" /* ErrorCode.TOKEN_UPDATE_FAILED */, {
|
|
411
|
+
errorInfo: message
|
|
412
|
+
});
|
|
413
|
+
}
|
|
414
|
+
if (!responseData.token) {
|
|
415
|
+
throw ERROR_FACTORY.create("token-update-no-token" /* ErrorCode.TOKEN_UPDATE_NO_TOKEN */);
|
|
416
|
+
}
|
|
417
|
+
return responseData.token;
|
|
522
418
|
}
|
|
523
|
-
function requestDeleteToken(firebaseDependencies, token) {
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
case 4:
|
|
543
|
-
responseData = _a.sent();
|
|
544
|
-
if (responseData.error) {
|
|
545
|
-
message = responseData.error.message;
|
|
546
|
-
throw ERROR_FACTORY.create("token-unsubscribe-failed" /* ErrorCode.TOKEN_UNSUBSCRIBE_FAILED */, {
|
|
547
|
-
errorInfo: message
|
|
548
|
-
});
|
|
549
|
-
}
|
|
550
|
-
return [3 /*break*/, 6];
|
|
551
|
-
case 5:
|
|
552
|
-
err_3 = _a.sent();
|
|
553
|
-
throw ERROR_FACTORY.create("token-unsubscribe-failed" /* ErrorCode.TOKEN_UNSUBSCRIBE_FAILED */, {
|
|
554
|
-
errorInfo: err_3 === null || err_3 === void 0 ? void 0 : err_3.toString()
|
|
555
|
-
});
|
|
556
|
-
case 6: return [2 /*return*/];
|
|
557
|
-
}
|
|
419
|
+
async function requestDeleteToken(firebaseDependencies, token) {
|
|
420
|
+
const headers = await getHeaders(firebaseDependencies);
|
|
421
|
+
const unsubscribeOptions = {
|
|
422
|
+
method: 'DELETE',
|
|
423
|
+
headers
|
|
424
|
+
};
|
|
425
|
+
try {
|
|
426
|
+
const response = await fetch(`${getEndpoint(firebaseDependencies.appConfig)}/${token}`, unsubscribeOptions);
|
|
427
|
+
const responseData = await response.json();
|
|
428
|
+
if (responseData.error) {
|
|
429
|
+
const message = responseData.error.message;
|
|
430
|
+
throw ERROR_FACTORY.create("token-unsubscribe-failed" /* ErrorCode.TOKEN_UNSUBSCRIBE_FAILED */, {
|
|
431
|
+
errorInfo: message
|
|
432
|
+
});
|
|
433
|
+
}
|
|
434
|
+
}
|
|
435
|
+
catch (err) {
|
|
436
|
+
throw ERROR_FACTORY.create("token-unsubscribe-failed" /* ErrorCode.TOKEN_UNSUBSCRIBE_FAILED */, {
|
|
437
|
+
errorInfo: err === null || err === void 0 ? void 0 : err.toString()
|
|
558
438
|
});
|
|
559
|
-
}
|
|
439
|
+
}
|
|
560
440
|
}
|
|
561
|
-
function getEndpoint(
|
|
562
|
-
|
|
563
|
-
return "".concat(ENDPOINT, "/projects/").concat(projectId, "/registrations");
|
|
441
|
+
function getEndpoint({ projectId }) {
|
|
442
|
+
return `${ENDPOINT}/projects/${projectId}/registrations`;
|
|
564
443
|
}
|
|
565
|
-
function getHeaders(
|
|
566
|
-
|
|
567
|
-
return
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
case 1:
|
|
573
|
-
authToken = _b.sent();
|
|
574
|
-
return [2 /*return*/, new Headers({
|
|
575
|
-
'Content-Type': 'application/json',
|
|
576
|
-
Accept: 'application/json',
|
|
577
|
-
'x-goog-api-key': appConfig.apiKey,
|
|
578
|
-
'x-goog-firebase-installations-auth': "FIS ".concat(authToken)
|
|
579
|
-
})];
|
|
580
|
-
}
|
|
581
|
-
});
|
|
444
|
+
async function getHeaders({ appConfig, installations }) {
|
|
445
|
+
const authToken = await installations.getToken();
|
|
446
|
+
return new Headers({
|
|
447
|
+
'Content-Type': 'application/json',
|
|
448
|
+
Accept: 'application/json',
|
|
449
|
+
'x-goog-api-key': appConfig.apiKey,
|
|
450
|
+
'x-goog-firebase-installations-auth': `FIS ${authToken}`
|
|
582
451
|
});
|
|
583
452
|
}
|
|
584
|
-
function getBody(
|
|
585
|
-
|
|
586
|
-
var body = {
|
|
453
|
+
function getBody({ p256dh, auth, endpoint, vapidKey }) {
|
|
454
|
+
const body = {
|
|
587
455
|
web: {
|
|
588
|
-
endpoint
|
|
589
|
-
auth
|
|
590
|
-
p256dh
|
|
456
|
+
endpoint,
|
|
457
|
+
auth,
|
|
458
|
+
p256dh
|
|
591
459
|
}
|
|
592
460
|
};
|
|
593
461
|
if (vapidKey !== DEFAULT_VAPID_KEY) {
|
|
@@ -613,169 +481,107 @@ function getBody(_a) {
|
|
|
613
481
|
* limitations under the License.
|
|
614
482
|
*/
|
|
615
483
|
// UpdateRegistration will be called once every week.
|
|
616
|
-
|
|
617
|
-
function getTokenInternal(messaging) {
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
e_1 = _a.sent();
|
|
649
|
-
// Suppress errors because of #2364
|
|
650
|
-
console.warn(e_1);
|
|
651
|
-
return [3 /*break*/, 7];
|
|
652
|
-
case 7: return [2 /*return*/, getNewToken(messaging.firebaseDependencies, subscriptionOptions)];
|
|
653
|
-
case 8:
|
|
654
|
-
if (Date.now() >= tokenDetails.createTime + TOKEN_EXPIRATION_MS) {
|
|
655
|
-
// Weekly token refresh
|
|
656
|
-
return [2 /*return*/, updateToken(messaging, {
|
|
657
|
-
token: tokenDetails.token,
|
|
658
|
-
createTime: Date.now(),
|
|
659
|
-
subscriptionOptions: subscriptionOptions
|
|
660
|
-
})];
|
|
661
|
-
}
|
|
662
|
-
else {
|
|
663
|
-
// Valid token, nothing to do.
|
|
664
|
-
return [2 /*return*/, tokenDetails.token];
|
|
665
|
-
}
|
|
666
|
-
case 9: return [2 /*return*/];
|
|
667
|
-
}
|
|
484
|
+
const TOKEN_EXPIRATION_MS = 7 * 24 * 60 * 60 * 1000; // 7 days
|
|
485
|
+
async function getTokenInternal(messaging) {
|
|
486
|
+
const pushSubscription = await getPushSubscription(messaging.swRegistration, messaging.vapidKey);
|
|
487
|
+
const subscriptionOptions = {
|
|
488
|
+
vapidKey: messaging.vapidKey,
|
|
489
|
+
swScope: messaging.swRegistration.scope,
|
|
490
|
+
endpoint: pushSubscription.endpoint,
|
|
491
|
+
auth: arrayToBase64(pushSubscription.getKey('auth')),
|
|
492
|
+
p256dh: arrayToBase64(pushSubscription.getKey('p256dh'))
|
|
493
|
+
};
|
|
494
|
+
const tokenDetails = await dbGet(messaging.firebaseDependencies);
|
|
495
|
+
if (!tokenDetails) {
|
|
496
|
+
// No token, get a new one.
|
|
497
|
+
return getNewToken(messaging.firebaseDependencies, subscriptionOptions);
|
|
498
|
+
}
|
|
499
|
+
else if (!isTokenValid(tokenDetails.subscriptionOptions, subscriptionOptions)) {
|
|
500
|
+
// Invalid token, get a new one.
|
|
501
|
+
try {
|
|
502
|
+
await requestDeleteToken(messaging.firebaseDependencies, tokenDetails.token);
|
|
503
|
+
}
|
|
504
|
+
catch (e) {
|
|
505
|
+
// Suppress errors because of #2364
|
|
506
|
+
console.warn(e);
|
|
507
|
+
}
|
|
508
|
+
return getNewToken(messaging.firebaseDependencies, subscriptionOptions);
|
|
509
|
+
}
|
|
510
|
+
else if (Date.now() >= tokenDetails.createTime + TOKEN_EXPIRATION_MS) {
|
|
511
|
+
// Weekly token refresh
|
|
512
|
+
return updateToken(messaging, {
|
|
513
|
+
token: tokenDetails.token,
|
|
514
|
+
createTime: Date.now(),
|
|
515
|
+
subscriptionOptions
|
|
668
516
|
});
|
|
669
|
-
}
|
|
517
|
+
}
|
|
518
|
+
else {
|
|
519
|
+
// Valid token, nothing to do.
|
|
520
|
+
return tokenDetails.token;
|
|
521
|
+
}
|
|
670
522
|
}
|
|
671
523
|
/**
|
|
672
524
|
* This method deletes the token from the database, unsubscribes the token from FCM, and unregisters
|
|
673
525
|
* the push subscription if it exists.
|
|
674
526
|
*/
|
|
675
|
-
function deleteTokenInternal(messaging) {
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
case 3:
|
|
689
|
-
_a.sent();
|
|
690
|
-
_a.label = 4;
|
|
691
|
-
case 4: return [4 /*yield*/, messaging.swRegistration.pushManager.getSubscription()];
|
|
692
|
-
case 5:
|
|
693
|
-
pushSubscription = _a.sent();
|
|
694
|
-
if (pushSubscription) {
|
|
695
|
-
return [2 /*return*/, pushSubscription.unsubscribe()];
|
|
696
|
-
}
|
|
697
|
-
// If there's no SW, consider it a success.
|
|
698
|
-
return [2 /*return*/, true];
|
|
699
|
-
}
|
|
700
|
-
});
|
|
701
|
-
});
|
|
527
|
+
async function deleteTokenInternal(messaging) {
|
|
528
|
+
const tokenDetails = await dbGet(messaging.firebaseDependencies);
|
|
529
|
+
if (tokenDetails) {
|
|
530
|
+
await requestDeleteToken(messaging.firebaseDependencies, tokenDetails.token);
|
|
531
|
+
await dbRemove(messaging.firebaseDependencies);
|
|
532
|
+
}
|
|
533
|
+
// Unsubscribe from the push subscription.
|
|
534
|
+
const pushSubscription = await messaging.swRegistration.pushManager.getSubscription();
|
|
535
|
+
if (pushSubscription) {
|
|
536
|
+
return pushSubscription.unsubscribe();
|
|
537
|
+
}
|
|
538
|
+
// If there's no SW, consider it a success.
|
|
539
|
+
return true;
|
|
702
540
|
}
|
|
703
|
-
function updateToken(messaging, tokenDetails) {
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
updatedTokenDetails = tslib.__assign(tslib.__assign({}, tokenDetails), { token: updatedToken, createTime: Date.now() });
|
|
714
|
-
return [4 /*yield*/, dbSet(messaging.firebaseDependencies, updatedTokenDetails)];
|
|
715
|
-
case 2:
|
|
716
|
-
_a.sent();
|
|
717
|
-
return [2 /*return*/, updatedToken];
|
|
718
|
-
case 3:
|
|
719
|
-
e_2 = _a.sent();
|
|
720
|
-
throw e_2;
|
|
721
|
-
case 4: return [2 /*return*/];
|
|
722
|
-
}
|
|
723
|
-
});
|
|
724
|
-
});
|
|
541
|
+
async function updateToken(messaging, tokenDetails) {
|
|
542
|
+
try {
|
|
543
|
+
const updatedToken = await requestUpdateToken(messaging.firebaseDependencies, tokenDetails);
|
|
544
|
+
const updatedTokenDetails = Object.assign(Object.assign({}, tokenDetails), { token: updatedToken, createTime: Date.now() });
|
|
545
|
+
await dbSet(messaging.firebaseDependencies, updatedTokenDetails);
|
|
546
|
+
return updatedToken;
|
|
547
|
+
}
|
|
548
|
+
catch (e) {
|
|
549
|
+
throw e;
|
|
550
|
+
}
|
|
725
551
|
}
|
|
726
|
-
function getNewToken(firebaseDependencies, subscriptionOptions) {
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
token: token,
|
|
736
|
-
createTime: Date.now(),
|
|
737
|
-
subscriptionOptions: subscriptionOptions
|
|
738
|
-
};
|
|
739
|
-
return [4 /*yield*/, dbSet(firebaseDependencies, tokenDetails)];
|
|
740
|
-
case 2:
|
|
741
|
-
_a.sent();
|
|
742
|
-
return [2 /*return*/, tokenDetails.token];
|
|
743
|
-
}
|
|
744
|
-
});
|
|
745
|
-
});
|
|
552
|
+
async function getNewToken(firebaseDependencies, subscriptionOptions) {
|
|
553
|
+
const token = await requestGetToken(firebaseDependencies, subscriptionOptions);
|
|
554
|
+
const tokenDetails = {
|
|
555
|
+
token,
|
|
556
|
+
createTime: Date.now(),
|
|
557
|
+
subscriptionOptions
|
|
558
|
+
};
|
|
559
|
+
await dbSet(firebaseDependencies, tokenDetails);
|
|
560
|
+
return tokenDetails.token;
|
|
746
561
|
}
|
|
747
562
|
/**
|
|
748
563
|
* Gets a PushSubscription for the current user.
|
|
749
564
|
*/
|
|
750
|
-
function getPushSubscription(swRegistration, vapidKey) {
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
return
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
}
|
|
761
|
-
return [2 /*return*/, swRegistration.pushManager.subscribe({
|
|
762
|
-
userVisibleOnly: true,
|
|
763
|
-
// Chrome <= 75 doesn't support base64-encoded VAPID key. For backward compatibility, VAPID key
|
|
764
|
-
// submitted to pushManager#subscribe must be of type Uint8Array.
|
|
765
|
-
applicationServerKey: base64ToArray(vapidKey)
|
|
766
|
-
})];
|
|
767
|
-
}
|
|
768
|
-
});
|
|
565
|
+
async function getPushSubscription(swRegistration, vapidKey) {
|
|
566
|
+
const subscription = await swRegistration.pushManager.getSubscription();
|
|
567
|
+
if (subscription) {
|
|
568
|
+
return subscription;
|
|
569
|
+
}
|
|
570
|
+
return swRegistration.pushManager.subscribe({
|
|
571
|
+
userVisibleOnly: true,
|
|
572
|
+
// Chrome <= 75 doesn't support base64-encoded VAPID key. For backward compatibility, VAPID key
|
|
573
|
+
// submitted to pushManager#subscribe must be of type Uint8Array.
|
|
574
|
+
applicationServerKey: base64ToArray(vapidKey)
|
|
769
575
|
});
|
|
770
576
|
}
|
|
771
577
|
/**
|
|
772
578
|
* Checks if the saved tokenDetails object matches the configuration provided.
|
|
773
579
|
*/
|
|
774
580
|
function isTokenValid(dbOptions, currentOptions) {
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
581
|
+
const isVapidKeyEqual = currentOptions.vapidKey === dbOptions.vapidKey;
|
|
582
|
+
const isEndpointEqual = currentOptions.endpoint === dbOptions.endpoint;
|
|
583
|
+
const isAuthEqual = currentOptions.auth === dbOptions.auth;
|
|
584
|
+
const isP256dhEqual = currentOptions.p256dh === dbOptions.p256dh;
|
|
779
585
|
return isVapidKeyEqual && isEndpointEqual && isAuthEqual && isP256dhEqual;
|
|
780
586
|
}
|
|
781
587
|
|
|
@@ -796,7 +602,7 @@ function isTokenValid(dbOptions, currentOptions) {
|
|
|
796
602
|
* limitations under the License.
|
|
797
603
|
*/
|
|
798
604
|
function externalizePayload(internalPayload) {
|
|
799
|
-
|
|
605
|
+
const payload = {
|
|
800
606
|
from: internalPayload.from,
|
|
801
607
|
// eslint-disable-next-line camelcase
|
|
802
608
|
collapseKey: internalPayload.collapse_key,
|
|
@@ -813,19 +619,19 @@ function propagateNotificationPayload(payload, messagePayloadInternal) {
|
|
|
813
619
|
return;
|
|
814
620
|
}
|
|
815
621
|
payload.notification = {};
|
|
816
|
-
|
|
622
|
+
const title = messagePayloadInternal.notification.title;
|
|
817
623
|
if (!!title) {
|
|
818
624
|
payload.notification.title = title;
|
|
819
625
|
}
|
|
820
|
-
|
|
626
|
+
const body = messagePayloadInternal.notification.body;
|
|
821
627
|
if (!!body) {
|
|
822
628
|
payload.notification.body = body;
|
|
823
629
|
}
|
|
824
|
-
|
|
630
|
+
const image = messagePayloadInternal.notification.image;
|
|
825
631
|
if (!!image) {
|
|
826
632
|
payload.notification.image = image;
|
|
827
633
|
}
|
|
828
|
-
|
|
634
|
+
const icon = messagePayloadInternal.notification.icon;
|
|
829
635
|
if (!!icon) {
|
|
830
636
|
payload.notification.icon = icon;
|
|
831
637
|
}
|
|
@@ -844,12 +650,12 @@ function propagateFcmOptions(payload, messagePayloadInternal) {
|
|
|
844
650
|
return;
|
|
845
651
|
}
|
|
846
652
|
payload.fcmOptions = {};
|
|
847
|
-
|
|
653
|
+
const link = (_c = (_b = messagePayloadInternal.fcmOptions) === null || _b === void 0 ? void 0 : _b.link) !== null && _c !== void 0 ? _c : (_d = messagePayloadInternal.notification) === null || _d === void 0 ? void 0 : _d.click_action;
|
|
848
654
|
if (!!link) {
|
|
849
655
|
payload.fcmOptions.link = link;
|
|
850
656
|
}
|
|
851
657
|
// eslint-disable-next-line camelcase
|
|
852
|
-
|
|
658
|
+
const analyticsLabel = (_e = messagePayloadInternal.fcmOptions) === null || _e === void 0 ? void 0 : _e.analytics_label;
|
|
853
659
|
if (!!analyticsLabel) {
|
|
854
660
|
payload.fcmOptions.analyticsLabel = analyticsLabel;
|
|
855
661
|
}
|
|
@@ -894,7 +700,7 @@ function isConsoleMessage(data) {
|
|
|
894
700
|
*/
|
|
895
701
|
/** Returns a promise that resolves after given time passes. */
|
|
896
702
|
function sleep(ms) {
|
|
897
|
-
return new Promise(
|
|
703
|
+
return new Promise(resolve => {
|
|
898
704
|
setTimeout(resolve, ms);
|
|
899
705
|
});
|
|
900
706
|
}
|
|
@@ -916,26 +722,13 @@ function sleep(ms) {
|
|
|
916
722
|
* limitations under the License.
|
|
917
723
|
*/
|
|
918
724
|
_mergeStrings('AzSCbw63g1R0nCw85jG8', 'Iaya3yLKwmgvh7cF0q4');
|
|
919
|
-
function stageLog(messaging, internalPayload) {
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
return tslib.__generator(this, function (_c) {
|
|
923
|
-
switch (_c.label) {
|
|
924
|
-
case 0:
|
|
925
|
-
_a = createFcmEvent;
|
|
926
|
-
_b = [internalPayload];
|
|
927
|
-
return [4 /*yield*/, messaging.firebaseDependencies.installations.getId()];
|
|
928
|
-
case 1:
|
|
929
|
-
fcmEvent = _a.apply(void 0, _b.concat([_c.sent()]));
|
|
930
|
-
createAndEnqueueLogEvent(messaging, fcmEvent, internalPayload.productId);
|
|
931
|
-
return [2 /*return*/];
|
|
932
|
-
}
|
|
933
|
-
});
|
|
934
|
-
});
|
|
725
|
+
async function stageLog(messaging, internalPayload) {
|
|
726
|
+
const fcmEvent = createFcmEvent(internalPayload, await messaging.firebaseDependencies.installations.getId());
|
|
727
|
+
createAndEnqueueLogEvent(messaging, fcmEvent, internalPayload.productId);
|
|
935
728
|
}
|
|
936
729
|
function createFcmEvent(internalPayload, fid) {
|
|
937
730
|
var _a, _b;
|
|
938
|
-
|
|
731
|
+
const fcmEvent = {};
|
|
939
732
|
/* eslint-disable camelcase */
|
|
940
733
|
// some fields should always be non-null. Still check to ensure.
|
|
941
734
|
if (!!internalPayload.from) {
|
|
@@ -964,7 +757,7 @@ function createFcmEvent(internalPayload, fid) {
|
|
|
964
757
|
return fcmEvent;
|
|
965
758
|
}
|
|
966
759
|
function createAndEnqueueLogEvent(messaging, fcmEvent, productId) {
|
|
967
|
-
|
|
760
|
+
const logEvent = {};
|
|
968
761
|
/* eslint-disable camelcase */
|
|
969
762
|
logEvent.event_time_ms = Math.floor(Date.now()).toString();
|
|
970
763
|
logEvent.source_extension_json_proto3 = JSON.stringify({
|
|
@@ -977,7 +770,7 @@ function createAndEnqueueLogEvent(messaging, fcmEvent, productId) {
|
|
|
977
770
|
messaging.logEvents.push(logEvent);
|
|
978
771
|
}
|
|
979
772
|
function buildComplianceData(productId) {
|
|
980
|
-
|
|
773
|
+
const complianceData = {
|
|
981
774
|
privacy_context: {
|
|
982
775
|
prequest: {
|
|
983
776
|
origin_associated_product_id: productId
|
|
@@ -987,8 +780,8 @@ function buildComplianceData(productId) {
|
|
|
987
780
|
return complianceData;
|
|
988
781
|
}
|
|
989
782
|
function _mergeStrings(s1, s2) {
|
|
990
|
-
|
|
991
|
-
for (
|
|
783
|
+
const resultArray = [];
|
|
784
|
+
for (let i = 0; i < s1.length; i++) {
|
|
992
785
|
resultArray.push(s1.charAt(i));
|
|
993
786
|
if (i < s2.length) {
|
|
994
787
|
resultArray.push(s2.charAt(i));
|
|
@@ -1013,155 +806,106 @@ function _mergeStrings(s1, s2) {
|
|
|
1013
806
|
* See the License for the specific language governing permissions and
|
|
1014
807
|
* limitations under the License.
|
|
1015
808
|
*/
|
|
1016
|
-
function onSubChange(event, messaging) {
|
|
809
|
+
async function onSubChange(event, messaging) {
|
|
1017
810
|
var _a, _b;
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
_c.sent();
|
|
1030
|
-
return [2 /*return*/];
|
|
1031
|
-
case 2: return [4 /*yield*/, dbGet(messaging.firebaseDependencies)];
|
|
1032
|
-
case 3:
|
|
1033
|
-
tokenDetails = _c.sent();
|
|
1034
|
-
return [4 /*yield*/, deleteTokenInternal(messaging)];
|
|
1035
|
-
case 4:
|
|
1036
|
-
_c.sent();
|
|
1037
|
-
messaging.vapidKey =
|
|
1038
|
-
(_b = (_a = tokenDetails === null || tokenDetails === void 0 ? void 0 : tokenDetails.subscriptionOptions) === null || _a === void 0 ? void 0 : _a.vapidKey) !== null && _b !== void 0 ? _b : DEFAULT_VAPID_KEY;
|
|
1039
|
-
return [4 /*yield*/, getTokenInternal(messaging)];
|
|
1040
|
-
case 5:
|
|
1041
|
-
_c.sent();
|
|
1042
|
-
return [2 /*return*/];
|
|
1043
|
-
}
|
|
1044
|
-
});
|
|
1045
|
-
});
|
|
811
|
+
const { newSubscription } = event;
|
|
812
|
+
if (!newSubscription) {
|
|
813
|
+
// Subscription revoked, delete token
|
|
814
|
+
await deleteTokenInternal(messaging);
|
|
815
|
+
return;
|
|
816
|
+
}
|
|
817
|
+
const tokenDetails = await dbGet(messaging.firebaseDependencies);
|
|
818
|
+
await deleteTokenInternal(messaging);
|
|
819
|
+
messaging.vapidKey =
|
|
820
|
+
(_b = (_a = tokenDetails === null || tokenDetails === void 0 ? void 0 : tokenDetails.subscriptionOptions) === null || _a === void 0 ? void 0 : _a.vapidKey) !== null && _b !== void 0 ? _b : DEFAULT_VAPID_KEY;
|
|
821
|
+
await getTokenInternal(messaging);
|
|
1046
822
|
}
|
|
1047
|
-
function onPush(event, messaging) {
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
if (!!!messaging.onBackgroundMessageHandler) return [3 /*break*/, 8];
|
|
1079
|
-
payload = externalizePayload(internalPayload);
|
|
1080
|
-
if (!(typeof messaging.onBackgroundMessageHandler === 'function')) return [3 /*break*/, 7];
|
|
1081
|
-
return [4 /*yield*/, messaging.onBackgroundMessageHandler(payload)];
|
|
1082
|
-
case 6:
|
|
1083
|
-
_a.sent();
|
|
1084
|
-
return [3 /*break*/, 8];
|
|
1085
|
-
case 7:
|
|
1086
|
-
messaging.onBackgroundMessageHandler.next(payload);
|
|
1087
|
-
_a.label = 8;
|
|
1088
|
-
case 8: return [2 /*return*/];
|
|
1089
|
-
}
|
|
1090
|
-
});
|
|
1091
|
-
});
|
|
823
|
+
async function onPush(event, messaging) {
|
|
824
|
+
const internalPayload = getMessagePayloadInternal(event);
|
|
825
|
+
if (!internalPayload) {
|
|
826
|
+
// Failed to get parsed MessagePayload from the PushEvent. Skip handling the push.
|
|
827
|
+
return;
|
|
828
|
+
}
|
|
829
|
+
// log to Firelog with user consent
|
|
830
|
+
if (messaging.deliveryMetricsExportedToBigQueryEnabled) {
|
|
831
|
+
await stageLog(messaging, internalPayload);
|
|
832
|
+
}
|
|
833
|
+
// foreground handling: eventually passed to onMessage hook
|
|
834
|
+
const clientList = await getClientList();
|
|
835
|
+
if (hasVisibleClients(clientList)) {
|
|
836
|
+
return sendMessagePayloadInternalToWindows(clientList, internalPayload);
|
|
837
|
+
}
|
|
838
|
+
// background handling: display if possible and pass to onBackgroundMessage hook
|
|
839
|
+
if (!!internalPayload.notification) {
|
|
840
|
+
await showNotification(wrapInternalPayload(internalPayload));
|
|
841
|
+
}
|
|
842
|
+
if (!messaging) {
|
|
843
|
+
return;
|
|
844
|
+
}
|
|
845
|
+
if (!!messaging.onBackgroundMessageHandler) {
|
|
846
|
+
const payload = externalizePayload(internalPayload);
|
|
847
|
+
if (typeof messaging.onBackgroundMessageHandler === 'function') {
|
|
848
|
+
await messaging.onBackgroundMessageHandler(payload);
|
|
849
|
+
}
|
|
850
|
+
else {
|
|
851
|
+
messaging.onBackgroundMessageHandler.next(payload);
|
|
852
|
+
}
|
|
853
|
+
}
|
|
1092
854
|
}
|
|
1093
|
-
function onNotificationClick(event) {
|
|
855
|
+
async function onNotificationClick(event) {
|
|
1094
856
|
var _a, _b;
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
return
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
return [3 /*break*/, 6];
|
|
1136
|
-
case 4: return [4 /*yield*/, client.focus()];
|
|
1137
|
-
case 5:
|
|
1138
|
-
client = _c.sent();
|
|
1139
|
-
_c.label = 6;
|
|
1140
|
-
case 6:
|
|
1141
|
-
if (!client) {
|
|
1142
|
-
// Window Client will not be returned if it's for a third party origin.
|
|
1143
|
-
return [2 /*return*/];
|
|
1144
|
-
}
|
|
1145
|
-
internalPayload.messageType = MessageType.NOTIFICATION_CLICKED;
|
|
1146
|
-
internalPayload.isFirebaseMessaging = true;
|
|
1147
|
-
return [2 /*return*/, client.postMessage(internalPayload)];
|
|
1148
|
-
}
|
|
1149
|
-
});
|
|
1150
|
-
});
|
|
857
|
+
const internalPayload = (_b = (_a = event.notification) === null || _a === void 0 ? void 0 : _a.data) === null || _b === void 0 ? void 0 : _b[FCM_MSG];
|
|
858
|
+
if (!internalPayload) {
|
|
859
|
+
return;
|
|
860
|
+
}
|
|
861
|
+
else if (event.action) {
|
|
862
|
+
// User clicked on an action button. This will allow developers to act on action button clicks
|
|
863
|
+
// by using a custom onNotificationClick listener that they define.
|
|
864
|
+
return;
|
|
865
|
+
}
|
|
866
|
+
// Prevent other listeners from receiving the event
|
|
867
|
+
event.stopImmediatePropagation();
|
|
868
|
+
event.notification.close();
|
|
869
|
+
// Note clicking on a notification with no link set will focus the Chrome's current tab.
|
|
870
|
+
const link = getLink(internalPayload);
|
|
871
|
+
if (!link) {
|
|
872
|
+
return;
|
|
873
|
+
}
|
|
874
|
+
// FM should only open/focus links from app's origin.
|
|
875
|
+
const url = new URL(link, self.location.href);
|
|
876
|
+
const originUrl = new URL(self.location.origin);
|
|
877
|
+
if (url.host !== originUrl.host) {
|
|
878
|
+
return;
|
|
879
|
+
}
|
|
880
|
+
let client = await getWindowClient(url);
|
|
881
|
+
if (!client) {
|
|
882
|
+
client = await self.clients.openWindow(link);
|
|
883
|
+
// Wait three seconds for the client to initialize and set up the message handler so that it
|
|
884
|
+
// can receive the message.
|
|
885
|
+
await sleep(3000);
|
|
886
|
+
}
|
|
887
|
+
else {
|
|
888
|
+
client = await client.focus();
|
|
889
|
+
}
|
|
890
|
+
if (!client) {
|
|
891
|
+
// Window Client will not be returned if it's for a third party origin.
|
|
892
|
+
return;
|
|
893
|
+
}
|
|
894
|
+
internalPayload.messageType = MessageType.NOTIFICATION_CLICKED;
|
|
895
|
+
internalPayload.isFirebaseMessaging = true;
|
|
896
|
+
return client.postMessage(internalPayload);
|
|
1151
897
|
}
|
|
1152
898
|
function wrapInternalPayload(internalPayload) {
|
|
1153
|
-
|
|
1154
|
-
var wrappedInternalPayload = tslib.__assign({}, internalPayload.notification);
|
|
899
|
+
const wrappedInternalPayload = Object.assign({}, internalPayload.notification);
|
|
1155
900
|
// Put the message payload under FCM_MSG name so we can identify the notification as being an FCM
|
|
1156
901
|
// notification vs a notification from somewhere else (i.e. normal web push or developer generated
|
|
1157
902
|
// notification).
|
|
1158
|
-
wrappedInternalPayload.data =
|
|
1159
|
-
|
|
1160
|
-
|
|
903
|
+
wrappedInternalPayload.data = {
|
|
904
|
+
[FCM_MSG]: internalPayload
|
|
905
|
+
};
|
|
1161
906
|
return wrappedInternalPayload;
|
|
1162
907
|
}
|
|
1163
|
-
function getMessagePayloadInternal(
|
|
1164
|
-
var data = _a.data;
|
|
908
|
+
function getMessagePayloadInternal({ data }) {
|
|
1165
909
|
if (!data) {
|
|
1166
910
|
return null;
|
|
1167
911
|
}
|
|
@@ -1177,64 +921,31 @@ function getMessagePayloadInternal(_a) {
|
|
|
1177
921
|
* @param url The URL to look for when focusing a client.
|
|
1178
922
|
* @return Returns an existing window client or a newly opened WindowClient.
|
|
1179
923
|
*/
|
|
1180
|
-
function getWindowClient(url) {
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
try {
|
|
1190
|
-
for (clientList_1 = tslib.__values(clientList), clientList_1_1 = clientList_1.next(); !clientList_1_1.done; clientList_1_1 = clientList_1.next()) {
|
|
1191
|
-
client = clientList_1_1.value;
|
|
1192
|
-
clientUrl = new URL(client.url, self.location.href);
|
|
1193
|
-
if (url.host === clientUrl.host) {
|
|
1194
|
-
return [2 /*return*/, client];
|
|
1195
|
-
}
|
|
1196
|
-
}
|
|
1197
|
-
}
|
|
1198
|
-
catch (e_1_1) { e_1 = { error: e_1_1 }; }
|
|
1199
|
-
finally {
|
|
1200
|
-
try {
|
|
1201
|
-
if (clientList_1_1 && !clientList_1_1.done && (_a = clientList_1.return)) _a.call(clientList_1);
|
|
1202
|
-
}
|
|
1203
|
-
finally { if (e_1) throw e_1.error; }
|
|
1204
|
-
}
|
|
1205
|
-
return [2 /*return*/, null];
|
|
1206
|
-
}
|
|
1207
|
-
});
|
|
1208
|
-
});
|
|
924
|
+
async function getWindowClient(url) {
|
|
925
|
+
const clientList = await getClientList();
|
|
926
|
+
for (const client of clientList) {
|
|
927
|
+
const clientUrl = new URL(client.url, self.location.href);
|
|
928
|
+
if (url.host === clientUrl.host) {
|
|
929
|
+
return client;
|
|
930
|
+
}
|
|
931
|
+
}
|
|
932
|
+
return null;
|
|
1209
933
|
}
|
|
1210
934
|
/**
|
|
1211
935
|
* @returns If there is currently a visible WindowClient, this method will resolve to true,
|
|
1212
936
|
* otherwise false.
|
|
1213
937
|
*/
|
|
1214
938
|
function hasVisibleClients(clientList) {
|
|
1215
|
-
return clientList.some(
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
!client.url.startsWith('chrome-extension://');
|
|
1220
|
-
});
|
|
939
|
+
return clientList.some(client => client.visibilityState === 'visible' &&
|
|
940
|
+
// Ignore chrome-extension clients as that matches the background pages of extensions, which
|
|
941
|
+
// are always considered visible for some reason.
|
|
942
|
+
!client.url.startsWith('chrome-extension://'));
|
|
1221
943
|
}
|
|
1222
944
|
function sendMessagePayloadInternalToWindows(clientList, internalPayload) {
|
|
1223
|
-
var e_2, _a;
|
|
1224
945
|
internalPayload.isFirebaseMessaging = true;
|
|
1225
946
|
internalPayload.messageType = MessageType.PUSH_RECEIVED;
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
var client = clientList_2_1.value;
|
|
1229
|
-
client.postMessage(internalPayload);
|
|
1230
|
-
}
|
|
1231
|
-
}
|
|
1232
|
-
catch (e_2_1) { e_2 = { error: e_2_1 }; }
|
|
1233
|
-
finally {
|
|
1234
|
-
try {
|
|
1235
|
-
if (clientList_2_1 && !clientList_2_1.done && (_a = clientList_2.return)) _a.call(clientList_2);
|
|
1236
|
-
}
|
|
1237
|
-
finally { if (e_2) throw e_2.error; }
|
|
947
|
+
for (const client of clientList) {
|
|
948
|
+
client.postMessage(internalPayload);
|
|
1238
949
|
}
|
|
1239
950
|
}
|
|
1240
951
|
function getClientList() {
|
|
@@ -1248,10 +959,10 @@ function showNotification(notificationPayloadInternal) {
|
|
|
1248
959
|
var _a;
|
|
1249
960
|
// Note: Firefox does not support the maxActions property.
|
|
1250
961
|
// https://developer.mozilla.org/en-US/docs/Web/API/notification/maxActions
|
|
1251
|
-
|
|
1252
|
-
|
|
962
|
+
const { actions } = notificationPayloadInternal;
|
|
963
|
+
const { maxActions } = Notification;
|
|
1253
964
|
if (actions && maxActions && actions.length > maxActions) {
|
|
1254
|
-
console.warn(
|
|
965
|
+
console.warn(`This browser only supports ${maxActions} actions. The remaining actions will not be displayed.`);
|
|
1255
966
|
}
|
|
1256
967
|
return self.registration.showNotification(
|
|
1257
968
|
/* title= */ (_a = notificationPayloadInternal.title) !== null && _a !== void 0 ? _a : '', notificationPayloadInternal);
|
|
@@ -1259,7 +970,7 @@ function showNotification(notificationPayloadInternal) {
|
|
|
1259
970
|
function getLink(payload) {
|
|
1260
971
|
var _a, _b, _c;
|
|
1261
972
|
// eslint-disable-next-line camelcase
|
|
1262
|
-
|
|
973
|
+
const link = (_b = (_a = payload.fcmOptions) === null || _a === void 0 ? void 0 : _a.link) !== null && _b !== void 0 ? _b : (_c = payload.notification) === null || _c === void 0 ? void 0 : _c.click_action;
|
|
1263
974
|
if (link) {
|
|
1264
975
|
return link;
|
|
1265
976
|
}
|
|
@@ -1289,7 +1000,6 @@ function getLink(payload) {
|
|
|
1289
1000
|
* limitations under the License.
|
|
1290
1001
|
*/
|
|
1291
1002
|
function extractAppConfig(app) {
|
|
1292
|
-
var e_1, _a;
|
|
1293
1003
|
if (!app || !app.options) {
|
|
1294
1004
|
throw getMissingValueError('App Configuration Object');
|
|
1295
1005
|
}
|
|
@@ -1297,28 +1007,18 @@ function extractAppConfig(app) {
|
|
|
1297
1007
|
throw getMissingValueError('App Name');
|
|
1298
1008
|
}
|
|
1299
1009
|
// Required app config keys
|
|
1300
|
-
|
|
1010
|
+
const configKeys = [
|
|
1301
1011
|
'projectId',
|
|
1302
1012
|
'apiKey',
|
|
1303
1013
|
'appId',
|
|
1304
1014
|
'messagingSenderId'
|
|
1305
1015
|
];
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
if (!options[keyName]) {
|
|
1311
|
-
throw getMissingValueError(keyName);
|
|
1312
|
-
}
|
|
1016
|
+
const { options } = app;
|
|
1017
|
+
for (const keyName of configKeys) {
|
|
1018
|
+
if (!options[keyName]) {
|
|
1019
|
+
throw getMissingValueError(keyName);
|
|
1313
1020
|
}
|
|
1314
1021
|
}
|
|
1315
|
-
catch (e_1_1) { e_1 = { error: e_1_1 }; }
|
|
1316
|
-
finally {
|
|
1317
|
-
try {
|
|
1318
|
-
if (configKeys_1_1 && !configKeys_1_1.done && (_a = configKeys_1.return)) _a.call(configKeys_1);
|
|
1319
|
-
}
|
|
1320
|
-
finally { if (e_1) throw e_1.error; }
|
|
1321
|
-
}
|
|
1322
1022
|
return {
|
|
1323
1023
|
appName: app.name,
|
|
1324
1024
|
projectId: options.projectId,
|
|
@@ -1329,7 +1029,7 @@ function extractAppConfig(app) {
|
|
|
1329
1029
|
}
|
|
1330
1030
|
function getMissingValueError(valueName) {
|
|
1331
1031
|
return ERROR_FACTORY.create("missing-app-config-values" /* ErrorCode.MISSING_APP_CONFIG_VALUES */, {
|
|
1332
|
-
valueName
|
|
1032
|
+
valueName
|
|
1333
1033
|
});
|
|
1334
1034
|
}
|
|
1335
1035
|
|
|
@@ -1349,27 +1049,26 @@ function getMissingValueError(valueName) {
|
|
|
1349
1049
|
* See the License for the specific language governing permissions and
|
|
1350
1050
|
* limitations under the License.
|
|
1351
1051
|
*/
|
|
1352
|
-
|
|
1353
|
-
|
|
1052
|
+
class MessagingService {
|
|
1053
|
+
constructor(app, installations, analyticsProvider) {
|
|
1354
1054
|
// logging is only done with end user consent. Default to false.
|
|
1355
1055
|
this.deliveryMetricsExportedToBigQueryEnabled = false;
|
|
1356
1056
|
this.onBackgroundMessageHandler = null;
|
|
1357
1057
|
this.onMessageHandler = null;
|
|
1358
1058
|
this.logEvents = [];
|
|
1359
1059
|
this.isLogServiceStarted = false;
|
|
1360
|
-
|
|
1060
|
+
const appConfig = extractAppConfig(app);
|
|
1361
1061
|
this.firebaseDependencies = {
|
|
1362
|
-
app
|
|
1363
|
-
appConfig
|
|
1364
|
-
installations
|
|
1365
|
-
analyticsProvider
|
|
1062
|
+
app,
|
|
1063
|
+
appConfig,
|
|
1064
|
+
installations,
|
|
1065
|
+
analyticsProvider
|
|
1366
1066
|
};
|
|
1367
1067
|
}
|
|
1368
|
-
|
|
1068
|
+
_delete() {
|
|
1369
1069
|
return Promise.resolve();
|
|
1370
|
-
}
|
|
1371
|
-
|
|
1372
|
-
}());
|
|
1070
|
+
}
|
|
1071
|
+
}
|
|
1373
1072
|
|
|
1374
1073
|
/**
|
|
1375
1074
|
* @license
|
|
@@ -1387,15 +1086,15 @@ var MessagingService = /** @class */ (function () {
|
|
|
1387
1086
|
* See the License for the specific language governing permissions and
|
|
1388
1087
|
* limitations under the License.
|
|
1389
1088
|
*/
|
|
1390
|
-
|
|
1391
|
-
|
|
1392
|
-
self.addEventListener('push',
|
|
1089
|
+
const SwMessagingFactory = (container) => {
|
|
1090
|
+
const messaging = new MessagingService(container.getProvider('app').getImmediate(), container.getProvider('installations-internal').getImmediate(), container.getProvider('analytics-internal'));
|
|
1091
|
+
self.addEventListener('push', e => {
|
|
1393
1092
|
e.waitUntil(onPush(e, messaging));
|
|
1394
1093
|
});
|
|
1395
|
-
self.addEventListener('pushsubscriptionchange',
|
|
1094
|
+
self.addEventListener('pushsubscriptionchange', e => {
|
|
1396
1095
|
e.waitUntil(onSubChange(e, messaging));
|
|
1397
1096
|
});
|
|
1398
|
-
self.addEventListener('notificationclick',
|
|
1097
|
+
self.addEventListener('notificationclick', e => {
|
|
1399
1098
|
e.waitUntil(onNotificationClick(e));
|
|
1400
1099
|
});
|
|
1401
1100
|
return messaging;
|
|
@@ -1431,30 +1130,16 @@ function registerMessagingInSw() {
|
|
|
1431
1130
|
*
|
|
1432
1131
|
* @public
|
|
1433
1132
|
*/
|
|
1434
|
-
function isSwSupported() {
|
|
1435
|
-
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
_a = (_b.sent());
|
|
1445
|
-
_b.label = 2;
|
|
1446
|
-
case 2:
|
|
1447
|
-
// firebase-js-sdk/issues/2393 reveals that idb#open in Safari iframe and Firefox private browsing
|
|
1448
|
-
// might be prohibited to run. In these contexts, an error would be thrown during the messaging
|
|
1449
|
-
// instantiating phase, informing the developers to import/call isSupported for special handling.
|
|
1450
|
-
return [2 /*return*/, (_a &&
|
|
1451
|
-
'PushManager' in self &&
|
|
1452
|
-
'Notification' in self &&
|
|
1453
|
-
ServiceWorkerRegistration.prototype.hasOwnProperty('showNotification') &&
|
|
1454
|
-
PushSubscription.prototype.hasOwnProperty('getKey'))];
|
|
1455
|
-
}
|
|
1456
|
-
});
|
|
1457
|
-
});
|
|
1133
|
+
async function isSwSupported() {
|
|
1134
|
+
// firebase-js-sdk/issues/2393 reveals that idb#open in Safari iframe and Firefox private browsing
|
|
1135
|
+
// might be prohibited to run. In these contexts, an error would be thrown during the messaging
|
|
1136
|
+
// instantiating phase, informing the developers to import/call isSupported for special handling.
|
|
1137
|
+
return (util.isIndexedDBAvailable() &&
|
|
1138
|
+
(await util.validateIndexedDBOpenable()) &&
|
|
1139
|
+
'PushManager' in self &&
|
|
1140
|
+
'Notification' in self &&
|
|
1141
|
+
ServiceWorkerRegistration.prototype.hasOwnProperty('showNotification') &&
|
|
1142
|
+
PushSubscription.prototype.hasOwnProperty('getKey'));
|
|
1458
1143
|
}
|
|
1459
1144
|
|
|
1460
1145
|
/**
|
|
@@ -1478,7 +1163,7 @@ function onBackgroundMessage$1(messaging, nextOrObserver) {
|
|
|
1478
1163
|
throw ERROR_FACTORY.create("only-available-in-sw" /* ErrorCode.AVAILABLE_IN_SW */);
|
|
1479
1164
|
}
|
|
1480
1165
|
messaging.onBackgroundMessageHandler = nextOrObserver;
|
|
1481
|
-
return
|
|
1166
|
+
return () => {
|
|
1482
1167
|
messaging.onBackgroundMessageHandler = null;
|
|
1483
1168
|
};
|
|
1484
1169
|
}
|
|
@@ -1527,18 +1212,17 @@ function _setDeliveryMetricsExportedToBigQueryEnabled(messaging, enable) {
|
|
|
1527
1212
|
*
|
|
1528
1213
|
* @public
|
|
1529
1214
|
*/
|
|
1530
|
-
function getMessagingInSw(app$1) {
|
|
1531
|
-
if (app$1 === void 0) { app$1 = app.getApp(); }
|
|
1215
|
+
function getMessagingInSw(app$1 = app.getApp()) {
|
|
1532
1216
|
// Conscious decision to make this async check non-blocking during the messaging instance
|
|
1533
1217
|
// initialization phase for performance consideration. An error would be thrown latter for
|
|
1534
1218
|
// developer's information. Developers can then choose to import and call `isSupported` for
|
|
1535
1219
|
// special handling.
|
|
1536
|
-
isSwSupported().then(
|
|
1220
|
+
isSwSupported().then(isSupported => {
|
|
1537
1221
|
// If `isSwSupported()` resolved, but returned false.
|
|
1538
1222
|
if (!isSupported) {
|
|
1539
1223
|
throw ERROR_FACTORY.create("unsupported-browser" /* ErrorCode.UNSUPPORTED_BROWSER */);
|
|
1540
1224
|
}
|
|
1541
|
-
},
|
|
1225
|
+
}, _ => {
|
|
1542
1226
|
// If `isSwSupported()` rejected.
|
|
1543
1227
|
throw ERROR_FACTORY.create("indexed-db-unsupported" /* ErrorCode.INDEXED_DB_UNSUPPORTED */);
|
|
1544
1228
|
});
|