Skip to content

Commit 2dab48d

Browse files
Fixes servicerworker/client state syncing (#1074)
* Fixes servicerworker/client state syncing Defines the MessageChannel based utility for communicating window <=> window and window <=> worker. Adds receiver in indexedDB when operating from a service worker to listen to keyChanged events. On detection, indexedDB is synced and a response is returned to sender whether the key change was processed. It may be that the key change was already detected. This would return false. Adds a sender when an indexedDB write operation occurs and a service worker is available. The client will send a keyChanged message to the service worker to process the change and blocks on it. On response, the indexedDB write operation will resolve. The operation will resolve on success or failure. This is a best effort approach. If the service worker fails to process, the write operation should still succeed. Updates obsoleted APIs in web worker.
1 parent c74c3b9 commit 2dab48d

File tree

12 files changed

+4782
-8
lines changed

12 files changed

+4782
-8
lines changed

packages/auth/demo/functions/yarn.lock

Lines changed: 2703 additions & 0 deletions
Large diffs are not rendered by default.

packages/auth/demo/public/web-worker.js

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -77,11 +77,11 @@ var runWorkerTests = function(googleIdToken) {
7777
firebase.auth().useDeviceLanguage();
7878
return firebase.auth().signInAnonymously();
7979
})
80-
.then(function(user) {
81-
if (!user.uid) {
80+
.then(function(result) {
81+
if (!result.user.uid) {
8282
throw new Error('signInAnonymously unexpectedly failed!');
8383
}
84-
return user.updateProfile({displayName: expectedDisplayName});
84+
return result.user.updateProfile({displayName: expectedDisplayName});
8585
})
8686
.then(function() {
8787
if (firebase.auth().currentUser.displayName != expectedDisplayName) {
@@ -95,8 +95,8 @@ var runWorkerTests = function(googleIdToken) {
9595
}
9696
return firebase.auth().createUserWithEmailAndPassword(email, pass);
9797
})
98-
.then(function(user) {
99-
if (user.email != email) {
98+
.then(function(result) {
99+
if (result.user.email != email) {
100100
throw new Error(
101101
'createUserWithEmailAndPassword unexpectedly failed!');
102102
}
@@ -107,11 +107,11 @@ var runWorkerTests = function(googleIdToken) {
107107
}
108108
return firebase.auth().signInWithEmailAndPassword(email, pass);
109109
})
110-
.then(function(user) {
111-
if (user.email != email) {
110+
.then(function(result) {
111+
if (result.user.email != email) {
112112
throw new Error('signInWithEmailAndPassword unexpectedly failed!');
113113
}
114-
return user.delete();
114+
return result.user.delete();
115115
})
116116
.then(function() {
117117
return firebase.auth().signInWithPopup(provider)
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
/**
2+
* Copyright 2018 Google Inc.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
/**
18+
* @fileoverview Defines the MessageChannel common utilities and enums.
19+
*/
20+
21+
goog.provide('fireauth.messagechannel.Error');
22+
goog.provide('fireauth.messagechannel.Status');
23+
goog.provide('fireauth.messagechannel.TimeoutDuration');
24+
goog.provide('fireauth.messagechannel.utils');
25+
26+
27+
/**
28+
* Enum for the messagechannel error messages. These errors are not meant to be
29+
* user facing.
30+
* @enum {string}
31+
*/
32+
fireauth.messagechannel.Error = {
33+
CONNECTION_UNAVAILABLE: 'connection_unavailable',
34+
INVALID_RESPONSE: 'invalid_response',
35+
TIMEOUT: 'timeout',
36+
UNKNOWN: 'unknown_error',
37+
UNSUPPORTED_EVENT: 'unsupported_event'
38+
};
39+
40+
41+
/**
42+
* Enum for the message channel request status labels.
43+
* @enum {string}
44+
*/
45+
fireauth.messagechannel.Status = {
46+
ACK: 'ack',
47+
DONE: 'done'
48+
};
49+
50+
51+
/**
52+
* Enum for the timeout durations in milliseconds for different contexts.
53+
* @enum {number}
54+
*/
55+
fireauth.messagechannel.TimeoutDuration = {
56+
ACK: 20,
57+
COMPLETION: 500
58+
};
59+
60+
61+
/**
62+
* @param {?string=} opt_prefix An optional prefix string to prepend to ID.
63+
* @param {?number=} opt_digits An optional number of digits used for event ID.
64+
* @return {string} The generated event ID used to identify a generic event.
65+
*/
66+
fireauth.messagechannel.utils.generateEventId =
67+
function(opt_prefix, opt_digits) {
68+
// 0, null and undefined will default to 20.
69+
var digits = opt_digits || 20;
70+
return opt_prefix ? opt_prefix : '' +
71+
Math.floor(Math.random() * Math.pow(10, digits)).toString();
72+
};
73+
74+
75+
/**
76+
* @return {?MessageChannel} The initialized MessageChannel instance if
77+
* supported.
78+
*/
79+
fireauth.messagechannel.utils.initializeMessageChannel = function() {
80+
return typeof MessageChannel !== 'undefined' ? new MessageChannel() : null;
81+
};
Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
/**
2+
* Copyright 2018 Google Inc.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
/**
18+
* @fileoverview Defines the PostMessager interface needed for the
19+
* `fireauth.messagechannel.Sender`, in addition to 2 types of implementations.
20+
*/
21+
22+
goog.provide('fireauth.messagechannel.PostMessager');
23+
goog.provide('fireauth.messagechannel.WindowPostMessager');
24+
goog.provide('fireauth.messagechannel.WorkerClientPostMessager');
25+
26+
27+
/**
28+
* This is the interface defining the postMessage format of a window which
29+
* takes an additional second parameter for target origin.
30+
*
31+
* @typedef {{
32+
* postMessage: function(*, string, !Array<!Transferable>)
33+
* }}
34+
*/
35+
fireauth.messagechannel.Window;
36+
37+
38+
/**
39+
* This is the interface defining the postMessage format of a worker or
40+
* ServiceWorkerClient, etc. which just takes a message and a list of
41+
* Transferables.
42+
*
43+
* @typedef {{
44+
* postMessage: function(*, !Array<!Transferable>)
45+
* }}
46+
*/
47+
fireauth.messagechannel.WorkerClient;
48+
49+
50+
/**
51+
* Defines a common interface to postMessage data to a specified PostMessager.
52+
* @interface
53+
*/
54+
fireauth.messagechannel.PostMessager = function() {};
55+
56+
57+
/**
58+
* Sends a message to the specified context.
59+
* @param {*} message The message to send.
60+
* @param {!Array<!Transferable>} transfer The list of `Transferable` objects
61+
* that are transferred with the message. The ownsership fo these objects is
62+
* given to the destination side and they are no longer usable on the
63+
* sending side.
64+
*/
65+
fireauth.messagechannel.PostMessager.prototype.postMessage =
66+
function(message, transfer) {};
67+
68+
69+
70+
/**
71+
* Defines the implementation for postMessaging to a window context.
72+
* @param {!fireauth.messagechannel.Window} win The window PostMessager.
73+
* @param {?string=} opt_targetOrigin The target origin.
74+
* @constructor
75+
* @implements {fireauth.messagechannel.PostMessager}
76+
*/
77+
fireauth.messagechannel.WindowPostMessager = function(win, opt_targetOrigin) {
78+
/**
79+
* @const @private {!fireauth.messagechannel.Window} The window PostMessager.
80+
*/
81+
this.win_ = win;
82+
/** @const @private {string} The postMessage target origin. */
83+
this.targetOrigin_ = opt_targetOrigin || '*';
84+
};
85+
86+
87+
/**
88+
* Sends a message to the specified window context.
89+
* @param {*} message The message to send.
90+
* @param {!Array<!Transferable>} transfer The list of `Transferable` objects
91+
* that are transferred with the message. The ownsership fo these objects is
92+
* given to the destination side and they are no longer usable on the
93+
* sending side.
94+
* @override
95+
*/
96+
fireauth.messagechannel.WindowPostMessager.prototype.postMessage =
97+
function(message, transfer) {
98+
this.win_.postMessage(message, this.targetOrigin_, transfer);
99+
};
100+
101+
102+
/**
103+
* Defines the implementation for postMessaging to a worker/client context.
104+
* @param {!fireauth.messagechannel.WorkerClient} worker The worker/client
105+
* PostMessager.
106+
* @constructor
107+
* @implements {fireauth.messagechannel.PostMessager}
108+
*/
109+
fireauth.messagechannel.WorkerClientPostMessager = function(worker) {
110+
/**
111+
* @const @private {!fireauth.messagechannel.WorkerClient} The worker/client
112+
* PostMessager.
113+
*/
114+
this.worker_ = worker;
115+
};
116+
117+
118+
/**
119+
* Sends a message to the specified worker/client context.
120+
* @param {*} message The message to send.
121+
* @param {!Array<!Transferable>} transfer The list of `Transferable` objects
122+
* that are transferred with the message. The ownsership fo these objects is
123+
* given to the destination side and they are no longer usable on the
124+
* sending side.
125+
* @override
126+
*/
127+
fireauth.messagechannel.WorkerClientPostMessager.prototype.postMessage =
128+
function(message, transfer) {
129+
this.worker_.postMessage(message, transfer);
130+
};

0 commit comments

Comments
 (0)