Skip to content

Commit 7513890

Browse files
authored
RTDB accepts multi region URL (#3050)
1 parent 094074c commit 7513890

File tree

3 files changed

+57
-15
lines changed

3 files changed

+57
-15
lines changed

packages/database/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
# Unreleased
22
- [feature] Added ServerValue.increment() to support atomic field value increments
33
without transactions.
4+
- [fixed] Fixed Realtime Database URL parsing bug to support domains with more than 3 components.
45

56
# Released
67
- [fixed] Fixed an issue that caused large numeric values with leading zeros to

packages/database/src/core/util/libs/parser.ts

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/**
22
* @license
3-
* Copyright 2017 Google Inc.
3+
* Copyright 2017 Google LLC
44
*
55
* Licensed under the Apache License, Version 2.0 (the "License");
66
* you may not use this file except in compliance with the License.
@@ -72,7 +72,7 @@ export const parseRepoInfo = function(
7272
const parsedUrl = parseDatabaseURL(dataURL),
7373
namespace = parsedUrl.namespace;
7474

75-
if (parsedUrl.domain === 'firebase') {
75+
if (parsedUrl.domain === 'firebase.com') {
7676
fatal(
7777
parsedUrl.host +
7878
' is no longer supported. ' +
@@ -171,20 +171,21 @@ export const parseDatabaseURL = function(
171171
secure = scheme === 'https' || scheme === 'wss';
172172
port = parseInt(host.substring(colonInd + 1), 10);
173173
} else {
174-
colonInd = dataURL.length;
174+
colonInd = host.length;
175175
}
176176

177-
const parts = host.split('.');
178-
if (parts.length === 3) {
177+
const hostWithoutPort = host.slice(0, colonInd);
178+
if (hostWithoutPort.toLowerCase() === 'localhost') {
179+
domain = 'localhost';
180+
} else if (hostWithoutPort.split('.').length <= 2) {
181+
domain = hostWithoutPort;
182+
} else {
183+
// Interpret the subdomain of a 3 or more component URL as the namespace name.
184+
const dotInd = host.indexOf('.');
185+
subdomain = host.substring(0, dotInd).toLowerCase();
186+
domain = host.substring(dotInd + 1);
179187
// Normalize namespaces to lowercase to share storage / connection.
180-
domain = parts[1];
181-
subdomain = parts[0].toLowerCase();
182-
// We interpret the subdomain of a 3 component URL as the namespace name.
183188
namespace = subdomain;
184-
} else if (parts.length === 2) {
185-
domain = parts[0];
186-
} else if (parts[0].slice(0, colonInd).toLowerCase() === 'localhost') {
187-
domain = 'localhost';
188189
}
189190
// Always treat the value of the `ns` as the namespace name if it is present.
190191
if ('ns' in queryParams) {

packages/database/test/database.test.ts

Lines changed: 43 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/**
22
* @license
3-
* Copyright 2017 Google Inc.
3+
* Copyright 2017 Google LLC
44
*
55
* Licensed under the Apache License, Version 2.0 (the "License");
66
* you may not use this file except in compliance with the License.
@@ -62,18 +62,49 @@ describe('Database Tests', () => {
6262
expect(db.ref().toString()).to.equal('https://foo.bar.com/');
6363
});
6464

65+
it('Can get database with multi-region URL', () => {
66+
const db = defaultApp.database('http://foo.euw1.firebasedatabase.app');
67+
expect(db).to.be.ok;
68+
expect(db.repo_.repoInfo_.namespace).to.equal('foo');
69+
expect(db.ref().toString()).to.equal(
70+
'https://foo.euw1.firebasedatabase.app/'
71+
);
72+
});
73+
74+
it('Can get database with upper case URL', () => {
75+
const db = defaultApp.database('http://fOO.EUW1.firebaseDATABASE.app');
76+
expect(db).to.be.ok;
77+
expect(db.repo_.repoInfo_.namespace).to.equal('foo');
78+
expect(db.ref().toString()).to.equal(
79+
'https://foo.euw1.firebasedatabase.app/'
80+
);
81+
});
82+
83+
it('Can get database with localhost URL', () => {
84+
const db = defaultApp.database('http://localhost');
85+
expect(db).to.be.ok;
86+
expect(db.ref().toString()).to.equal('https://localhost/');
87+
});
88+
6589
it('Can get database with localhost URL and port', () => {
6690
const db = defaultApp.database('http://localhost:80');
6791
expect(db).to.be.ok;
6892
expect(db.ref().toString()).to.equal('http://localhost:80/');
6993
});
7094

71-
it('Can get database with localhost URL', () => {
72-
const db = defaultApp.database('http://localhost');
95+
it('Can get database with a upper case localhost URL', () => {
96+
const db = defaultApp.database('http://LOCALHOST');
7397
expect(db).to.be.ok;
7498
expect(db.ref().toString()).to.equal('https://localhost/');
7599
});
76100

101+
it('Can get database with a upper case localhost URL and ns', () => {
102+
const db = defaultApp.database('http://LOCALHOST?ns=foo');
103+
expect(db).to.be.ok;
104+
expect(db.repo_.repoInfo_.namespace).to.equal('foo');
105+
expect(db.ref().toString()).to.equal('https://localhost/');
106+
});
107+
77108
it('Can read ns query param', () => {
78109
const db = defaultApp.database('http://localhost:80/?ns=foo&unused=true');
79110
expect(db).to.be.ok;
@@ -111,10 +142,19 @@ describe('Database Tests', () => {
111142
}).to.throw(/Database initialized multiple times/i);
112143
});
113144

145+
it('Databases with legacy domain', () => {
146+
expect(() => {
147+
defaultApp.database('http://foo.firebase.com/');
148+
}).to.throw(/is no longer supported/i);
149+
});
150+
114151
it('Databases with invalid custom URLs', () => {
115152
expect(() => {
116153
defaultApp.database('not-a-url');
117154
}).to.throw(/Cannot parse Firebase url/i);
155+
expect(() => {
156+
defaultApp.database('http://foo.com');
157+
}).to.throw(/Cannot parse Firebase url/i);
118158
expect(() => {
119159
defaultApp.database('http://fblocal.com');
120160
}).to.throw(/Cannot parse Firebase url/i);

0 commit comments

Comments
 (0)