Skip to content

Commit ac7f9ce

Browse files
Escpae the persistence key everywhere & scope online state by project (#1182)
1 parent 47d09ab commit ac7f9ce

File tree

2 files changed

+34
-20
lines changed

2 files changed

+34
-20
lines changed

packages/firestore/src/local/shared_client_state.ts

Lines changed: 33 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,10 @@ const MUTATION_BATCH_KEY_PREFIX = 'firestore_mutations';
5454
// firestore_targets_<persistence_prefix>_<target_id>
5555
const QUERY_TARGET_KEY_PREFIX = 'firestore_targets';
5656

57-
// The LocalStorage key that stores the primary tab's online state.
58-
const ONLINE_STATE_KEY = 'firestore_online_state';
57+
// The LocalStorage prefix that stores the primary tab's online state. The
58+
// format of the key is:
59+
// firestore_online_state_<persistence_prefix>
60+
const ONLINE_STATE_KEY_PREFIX = 'firestore_online_state';
5961

6062
/**
6163
* A randomly-generated key assigned to each Firestore instance at startup.
@@ -511,6 +513,8 @@ export class WebStorageSharedClientState implements SharedClientState {
511513
private readonly localClientStorageKey: string;
512514
private readonly activeClients: { [key: string]: ClientState } = {};
513515
private readonly storageListener = this.handleLocalStorageEvent.bind(this);
516+
private readonly escapedPersistenceKey: string;
517+
private readonly onlineStateKey: string;
514518
private readonly clientStateKeyRe: RegExp;
515519
private readonly mutationBatchKeyRe: RegExp;
516520
private readonly queryTargetKeyRe: RegExp;
@@ -526,7 +530,7 @@ export class WebStorageSharedClientState implements SharedClientState {
526530
constructor(
527531
private readonly queue: AsyncQueue,
528532
private readonly platform: Platform,
529-
private readonly persistenceKey: string,
533+
persistenceKey: string,
530534
private readonly localClientId: ClientId,
531535
initialUser: User
532536
) {
@@ -536,30 +540,36 @@ export class WebStorageSharedClientState implements SharedClientState {
536540
'LocalStorage is not available on this platform.'
537541
);
538542
}
543+
// Escape the special characters mentioned here:
544+
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions
545+
this.escapedPersistenceKey = persistenceKey.replace(
546+
/[.*+?^${}()|[\]\\]/g,
547+
'\\$&'
548+
);
549+
539550
this.storage = this.platform.window!.localStorage;
540551
this.currentUser = initialUser;
541552
this.localClientStorageKey = this.toLocalStorageClientStateKey(
542553
this.localClientId
543554
);
544555
this.activeClients[this.localClientId] = new LocalClientState();
545556

546-
// Escape the special characters mentioned here:
547-
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions
548-
const escapedPersistenceKey = persistenceKey.replace(
549-
/[.*+?^${}()|[\]\\]/g,
550-
'\\$&'
551-
);
552-
553557
this.clientStateKeyRe = new RegExp(
554-
`^${CLIENT_STATE_KEY_PREFIX}_${escapedPersistenceKey}_([^_]*)$`
558+
`^${CLIENT_STATE_KEY_PREFIX}_${this.escapedPersistenceKey}_([^_]*)$`
555559
);
556560
this.mutationBatchKeyRe = new RegExp(
557-
`^${MUTATION_BATCH_KEY_PREFIX}_${escapedPersistenceKey}_(\\d+)(?:_(.*))?$`
561+
`^${MUTATION_BATCH_KEY_PREFIX}_${
562+
this.escapedPersistenceKey
563+
}_(\\d+)(?:_(.*))?$`
558564
);
559565
this.queryTargetKeyRe = new RegExp(
560-
`^${QUERY_TARGET_KEY_PREFIX}_${escapedPersistenceKey}_(\\d+)$`
566+
`^${QUERY_TARGET_KEY_PREFIX}_${this.escapedPersistenceKey}_(\\d+)$`
561567
);
562568

569+
this.onlineStateKey = `${ONLINE_STATE_KEY_PREFIX}_${
570+
this.escapedPersistenceKey
571+
}`;
572+
563573
// Rather than adding the storage observer during start(), we add the
564574
// storage observer during initialization. This ensures that we collect
565575
// events before other components populate their initial state (during their
@@ -612,7 +622,7 @@ export class WebStorageSharedClientState implements SharedClientState {
612622

613623
// Check if there is an existing online state and call the callback handler
614624
// if applicable.
615-
const onlineStateJSON = this.storage.getItem(ONLINE_STATE_KEY);
625+
const onlineStateJSON = this.storage.getItem(this.onlineStateKey);
616626
if (onlineStateJSON) {
617627
const onlineState = this.fromLocalStorageOnlineState(onlineStateJSON);
618628
if (onlineState) {
@@ -821,7 +831,7 @@ export class WebStorageSharedClientState implements SharedClientState {
821831
return this.handleQueryTargetEvent(queryTargetMetadata);
822832
}
823833
}
824-
} else if (event.key === ONLINE_STATE_KEY) {
834+
} else if (event.key === this.onlineStateKey) {
825835
if (event.newValue !== null) {
826836
const onlineState = this.fromLocalStorageOnlineState(
827837
event.newValue
@@ -871,7 +881,7 @@ export class WebStorageSharedClientState implements SharedClientState {
871881
clientId: this.localClientId,
872882
onlineState: OnlineState[onlineState]
873883
};
874-
this.storage.setItem(ONLINE_STATE_KEY, JSON.stringify(entry));
884+
this.storage.setItem(this.onlineStateKey, JSON.stringify(entry));
875885
}
876886

877887
private persistQueryTargetState(
@@ -891,18 +901,22 @@ export class WebStorageSharedClientState implements SharedClientState {
891901
`Client key cannot contain '_', but was '${clientId}'`
892902
);
893903

894-
return `${CLIENT_STATE_KEY_PREFIX}_${this.persistenceKey}_${clientId}`;
904+
return `${CLIENT_STATE_KEY_PREFIX}_${
905+
this.escapedPersistenceKey
906+
}_${clientId}`;
895907
}
896908

897909
/** Assembles the key for a query state in LocalStorage */
898910
private toLocalStorageQueryTargetMetadataKey(targetId: TargetId): string {
899-
return `${QUERY_TARGET_KEY_PREFIX}_${this.persistenceKey}_${targetId}`;
911+
return `${QUERY_TARGET_KEY_PREFIX}_${
912+
this.escapedPersistenceKey
913+
}_${targetId}`;
900914
}
901915

902916
/** Assembles the key for a mutation batch in LocalStorage */
903917
private toLocalStorageMutationBatchKey(batchId: BatchId): string {
904918
let mutationKey = `${MUTATION_BATCH_KEY_PREFIX}_${
905-
this.persistenceKey
919+
this.escapedPersistenceKey
906920
}_${batchId}`;
907921

908922
if (this.currentUser.isAuthenticated()) {

packages/firestore/test/unit/local/web_storage_shared_client_state.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ function targetKey(targetId: TargetId): string {
7070
}
7171

7272
function onlineStateKey(): string {
73-
return 'firestore_online_state';
73+
return `firestore_online_state_${persistenceHelpers.TEST_PERSISTENCE_PREFIX}`;
7474
}
7575

7676
interface TestSharedClientState {

0 commit comments

Comments
 (0)