Skip to content

Commit 03e8422

Browse files
Package database compat (#4753)
* Add database@exp API (#4614) * Compat and @exp class for DataSnapshot (#4686) * Add events to database@exp (#4694) * Compat and @exp class for Database (#4705) * Implement Query Compat and query@exp (#4709) * Compat class for Reference (#4719) * OnDisconnect Compat (#4727) * ServerValues compat (#4728) * EnableLogging Compat (#4730) * Remove argument numbers from validation (#4729) * Update changeset * Add database@exp API docs (#4738) * Add Support for API report (#4741) * pacakge database compat * export child as a public API * address comments * create database-compat dir * create overloads for database-compat * build database * add database-compat to firebase-exp * fix lint errors * include compat in build * fix typing errors * fix script name * make database types compatible * use modular instance Co-authored-by: Sebastian Schmidt <mrschmidt@google.com>
1 parent 6db185b commit 03e8422

29 files changed

+637
-210
lines changed

common/api-review/database-exp.api.md

+3
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@
77
import { FirebaseApp } from '@firebase/app';
88

99
// @public (undocumented)
10+
export function child(parent: Reference, path: string): Reference;
11+
12+
// @public
1013
export class DataSnapshot {
1114
child(path: string): DataSnapshot;
1215
exists(): boolean;

integration/compat-typings/typings.ts

+21-46
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ import {
3535
FirebaseStorage,
3636
Reference as StorageReference
3737
} from '@firebase/storage-types';
38+
import { FirebaseDatabase, Reference, Query } from '@firebase/database-types';
3839

3940
/**
4041
* Test namespaced types from compat/index.d.ts against the types used in
@@ -45,38 +46,6 @@ import {
4546
* - app-compat, which defines its FirebaseApp type in its own package
4647
*/
4748

48-
const namespaced: {
49-
auth: firebase.auth.Auth;
50-
analytics: firebase.analytics.Analytics;
51-
app: firebase.app.App;
52-
firestore: firebase.firestore.Firestore;
53-
functions: firebase.functions.Functions;
54-
installations?: firebase.installations.Installations;
55-
messaging: firebase.messaging.Messaging;
56-
performance: firebase.performance.Performance;
57-
remoteConfig: firebase.remoteConfig.RemoteConfig;
58-
storage: firebase.storage.Storage;
59-
storageReference: firebase.storage.Reference;
60-
firestoreDocumentReference: firebase.firestore.DocumentReference;
61-
firestoreCollectionReference: firebase.firestore.CollectionReference;
62-
authUser: firebase.User;
63-
} = {
64-
auth: firebase.auth(),
65-
analytics: firebase.analytics(),
66-
app: firebase.initializeApp({}),
67-
firestore: firebase.firestore(),
68-
functions: firebase.functions(),
69-
installations: {} as firebase.installations.Installations,
70-
messaging: firebase.messaging(),
71-
performance: firebase.performance(),
72-
remoteConfig: firebase.remoteConfig(),
73-
storage: firebase.storage(),
74-
storageReference: {} as firebase.storage.Reference,
75-
firestoreDocumentReference: {} as firebase.firestore.DocumentReference,
76-
firestoreCollectionReference: {} as firebase.firestore.CollectionReference,
77-
authUser: {} as firebase.User
78-
};
79-
8049
const compatTypes: {
8150
auth: FirebaseAuth;
8251
analytics: FirebaseAnalytics;
@@ -92,19 +61,25 @@ const compatTypes: {
9261
firestoreDocumentReference: DocumentReference;
9362
firestoreCollectionReference: CollectionReference;
9463
authUser: User;
64+
database: FirebaseDatabase;
65+
databaseReference: Reference;
66+
databaseQuery: Query;
9567
} = {
96-
auth: namespaced.auth,
97-
analytics: namespaced.analytics,
98-
app: namespaced.app,
99-
firestore: namespaced.firestore,
100-
functions: namespaced.functions,
101-
installations: namespaced.installations,
102-
messaging: namespaced.messaging,
103-
performance: namespaced.performance,
104-
remoteConfig: namespaced.remoteConfig,
105-
storage: namespaced.storage,
106-
storageReference: namespaced.storageReference,
107-
firestoreDocumentReference: namespaced.firestoreDocumentReference,
108-
firestoreCollectionReference: namespaced.firestoreCollectionReference,
109-
authUser: namespaced.authUser
68+
auth: firebase.auth(),
69+
analytics: firebase.analytics(),
70+
app: firebase.initializeApp({}),
71+
firestore: firebase.firestore(),
72+
functions: firebase.functions(),
73+
installations: {} as firebase.installations.Installations,
74+
messaging: firebase.messaging(),
75+
performance: firebase.performance(),
76+
remoteConfig: firebase.remoteConfig(),
77+
storage: firebase.storage(),
78+
storageReference: {} as firebase.storage.Reference,
79+
firestoreDocumentReference: {} as firebase.firestore.DocumentReference,
80+
firestoreCollectionReference: {} as firebase.firestore.CollectionReference,
81+
authUser: {} as firebase.User,
82+
database: {} as firebase.database.Database,
83+
databaseReference: {} as firebase.database.Reference,
84+
databaseQuery: {} as firebase.database.Query
11085
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
/**
2+
* @license
3+
* Copyright 2021 Google LLC
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
import '@firebase/database-compat';
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"name": "firebase-exp/compat/database",
3+
"main": "dist/index.cjs.js",
4+
"browser": "dist/index.esm.js",
5+
"module": "dist/index.esm.js",
6+
"typings": "dist/compat/database/index.d.ts"
7+
}
8+

packages-exp/firebase-exp/compat/index.cdn.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ import firebase from './app';
3131
import { name, version } from '../package.json';
3232

3333
import './auth';
34-
// import './database';
34+
import './database';
3535
import './firestore';
3636
import './functions';
3737
import './messaging';

packages-exp/firebase-exp/compat/index.node.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ import firebase from './app';
1919
import { name, version } from '../package.json';
2020

2121
import './auth';
22-
// import './database';
22+
import './database';
2323
import './firestore';
2424
import './functions';
2525

packages-exp/firebase-exp/compat/index.rn.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ import firebase from './app';
1919
import { name, version } from '../package.json';
2020

2121
import './auth';
22-
// import './database';
22+
import './database';
2323
// // TODO(b/158625454): Storage doesn't actually work by default in RN (it uses
2424
// // `atob`). We should provide a RN build that works out of the box.
2525
// import './storage';

packages-exp/firebase-exp/compat/index.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ import firebase from './app';
4040
import { name, version } from '../package.json';
4141

4242
import './auth';
43-
// import './database';
43+
import './database';
4444
import './firestore';
4545
import './functions';
4646
import './messaging';

packages-exp/firebase-exp/compat/package.json

+2-1
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
"performance",
1515
"remote-config",
1616
"firestore",
17-
"storage"
17+
"storage",
18+
"database"
1819
]
1920
}

packages-exp/firebase-exp/compat/rollup.config.release.js

+5
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,11 @@ const componentBuilds = compatPkg.components
190190
// hack to locate storage-compat
191191
find: '@firebase/storage-compat',
192192
replacement: 'storage-compat'
193+
},
194+
{
195+
// hack to locate database-compat
196+
find: '@firebase/database-compat',
197+
replacement: 'database-compat'
193198
}
194199
]
195200
}),

packages/database-types/index.d.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ export interface Query {
8888
callback: (a: DataSnapshot, b?: string | null) => any,
8989
cancelCallbackOrContext?: ((a: Error) => any) | Object | null,
9090
context?: Object | null
91-
): (a: DataSnapshot, b?: string | null) => any;
91+
): (a: DataSnapshot | null, b?: string | null) => any;
9292
once(
9393
eventType: EventType,
9494
successCallback?: (a: DataSnapshot, b?: string | null) => any,
+154
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,154 @@
1+
/**
2+
* @license
3+
* Copyright 2021 Google LLC
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
import { FirebaseApp, FirebaseNamespace } from '@firebase/app-types';
19+
import { _FirebaseNamespace } from '@firebase/app-types/private';
20+
import { FirebaseAuthInternal } from '@firebase/auth-interop-types';
21+
import { Component, ComponentType } from '@firebase/component';
22+
import * as types from '@firebase/database-types';
23+
import { CONSTANTS, isNodeSdk } from '@firebase/util';
24+
import { Client } from 'faye-websocket';
25+
26+
import { enableLogging } from '../exp/index';
27+
import { Database } from '../src/api/Database';
28+
import * as INTERNAL from '../src/api/internal';
29+
import { DataSnapshot, Query, Reference } from '../src/api/Reference';
30+
import * as TEST_ACCESS from '../src/api/test_access';
31+
import { setSDKVersion } from '../src/core/version';
32+
import { setWebSocketImpl } from '../src/realtime/WebSocketConnection';
33+
34+
import { name, version } from './package.json';
35+
36+
setWebSocketImpl(Client);
37+
38+
const ServerValue = Database.ServerValue;
39+
40+
/**
41+
* A one off register function which returns a database based on the app and
42+
* passed database URL. (Used by the Admin SDK)
43+
*
44+
* @param app - A valid FirebaseApp-like object
45+
* @param url - A valid Firebase databaseURL
46+
* @param version - custom version e.g. firebase-admin version
47+
* @param nodeAdmin - true if the SDK is being initialized from Firebase Admin.
48+
*/
49+
export function initStandalone(
50+
app: FirebaseApp,
51+
url: string,
52+
version: string,
53+
nodeAdmin = true
54+
) {
55+
CONSTANTS.NODE_ADMIN = nodeAdmin;
56+
return INTERNAL.initStandalone({
57+
app,
58+
url,
59+
version,
60+
// firebase-admin-node's app.INTERNAL implements FirebaseAuthInternal interface
61+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
62+
customAuthImpl: (app as any).INTERNAL as FirebaseAuthInternal,
63+
namespace: {
64+
Reference,
65+
Query,
66+
Database,
67+
DataSnapshot,
68+
enableLogging,
69+
INTERNAL,
70+
ServerValue,
71+
TEST_ACCESS
72+
},
73+
nodeAdmin
74+
});
75+
}
76+
77+
export function registerDatabase(instance: FirebaseNamespace) {
78+
// set SDK_VERSION
79+
setSDKVersion(instance.SDK_VERSION);
80+
81+
// Register the Database Service with the 'firebase' namespace.
82+
const namespace = (instance as _FirebaseNamespace).INTERNAL.registerComponent(
83+
new Component(
84+
'database-compat',
85+
(container, { instanceIdentifier: url }) => {
86+
/* Dependencies */
87+
// getImmediate for FirebaseApp will always succeed
88+
const app = container.getProvider('app-compat').getImmediate();
89+
const databaseExp = container
90+
.getProvider('database-exp')
91+
.getImmediate({ identifier: url });
92+
return new Database(databaseExp, app);
93+
},
94+
ComponentType.PUBLIC
95+
)
96+
.setServiceProps(
97+
// firebase.database namespace properties
98+
{
99+
Reference,
100+
Query,
101+
Database,
102+
DataSnapshot,
103+
enableLogging,
104+
INTERNAL,
105+
ServerValue,
106+
TEST_ACCESS
107+
}
108+
)
109+
.setMultipleInstances(true)
110+
);
111+
112+
instance.registerVersion(name, version, 'node');
113+
114+
if (isNodeSdk()) {
115+
module.exports = Object.assign({}, namespace, { initStandalone });
116+
}
117+
}
118+
119+
try {
120+
// If @firebase/app is not present, skip registering database.
121+
// It could happen when this package is used in firebase-admin which doesn't depend on @firebase/app.
122+
// Previously firebase-admin depends on @firebase/app, which causes version conflict on
123+
// @firebase/app when used together with the js sdk. More detail:
124+
// https://github.com/firebase/firebase-js-sdk/issues/1696#issuecomment-501546596
125+
// eslint-disable-next-line import/no-extraneous-dependencies, @typescript-eslint/no-require-imports
126+
const firebase = require('@firebase/app-compat').default;
127+
registerDatabase(firebase);
128+
} catch (err) {
129+
// catch and ignore 'MODULE_NOT_FOUND' error in firebase-admin context
130+
// we can safely ignore this error because RTDB in firebase-admin works without @firebase/app
131+
if (err.code !== 'MODULE_NOT_FOUND') {
132+
throw err;
133+
}
134+
}
135+
136+
// Types to export for the admin SDK
137+
export { Database, Query, Reference, enableLogging, ServerValue };
138+
139+
export { OnDisconnect } from '../src/api/onDisconnect';
140+
141+
declare module '@firebase/app-compat' {
142+
interface FirebaseNamespace {
143+
database?: {
144+
(app?: FirebaseApp): types.FirebaseDatabase;
145+
enableLogging: typeof types.enableLogging;
146+
ServerValue: types.ServerValue;
147+
Database: typeof types.FirebaseDatabase;
148+
};
149+
}
150+
interface FirebaseApp {
151+
database?(): types.FirebaseDatabase;
152+
}
153+
}
154+
export { DataSnapshot } from '../src/api/Reference';

0 commit comments

Comments
 (0)