├── .editorconfig
├── .firebaserc
├── .gitattributes
├── .github
└── workflows
│ ├── codeql-analysis.yml
│ └── test.yml
├── .gitignore
├── .npmignore
├── .nvmrc
├── CONTRIBUTING.md
├── ISSUE_TEMPLATE.md
├── LICENSE
├── PULL_REQUEST_TEMPLATE.md
├── README.md
├── SECURITY.md
├── angular.json
├── docs
├── analytics.md
├── app-check.md
├── auth.md
├── compat.md
├── compat
│ ├── analytics
│ │ └── getting-started.md
│ ├── auth
│ │ ├── getting-started.md
│ │ └── router-guards.md
│ ├── emulators
│ │ └── emulators.md
│ ├── firestore
│ │ ├── collections.md
│ │ ├── documents.md
│ │ ├── offline-data.md
│ │ └── querying-collections.md
│ ├── functions
│ │ └── functions.md
│ ├── messaging
│ │ └── messaging.md
│ ├── performance
│ │ └── getting-started.md
│ ├── remote-config
│ │ └── getting-started.md
│ ├── rtdb
│ │ ├── lists.md
│ │ ├── objects.md
│ │ └── querying-lists.md
│ └── storage
│ │ └── storage.md
├── database.md
├── deploy
│ └── getting-started.md
├── firebase.json
├── firestore.md
├── functions.md
├── images
│ ├── analytics-illo_1x.png
│ ├── auth-illo_1x.png
│ ├── cloud-messaging-illo_1x.png
│ ├── database-illo_1x.png
│ ├── firestore-illo_1x.png
│ ├── functions-illo_1x.png
│ ├── hosting-illo_1x.png
│ ├── performance-illo_1x.png
│ ├── reCAPTCHA-logo@1x.png
│ ├── remote-config-illo_1x.png
│ └── storage-illo_1x.png
├── install-and-setup.md
├── install-angular-cli-windows10.md
├── install-firebase-tools.md
├── messaging.md
├── performance.md
├── remote-config.md
├── storage.md
├── universal
│ ├── cloud-functions.md
│ ├── getting-started.md
│ └── prerendering.md
├── version-4-upgrade.md
├── version-5-upgrade.md
├── version-6-upgrade.md
├── version-7-upgrade.md
├── vertexai.md
└── zones.md
├── eslint.config.js
├── firebase.json
├── karma.conf.js
├── package-lock.json
├── package.json
├── sample
├── .editorconfig
├── .firebaserc
├── .gitignore
├── README.md
├── angular.json
├── database.rules.json
├── firebase.json
├── firestore.indexes.json
├── firestore.rules
├── functions
│ ├── .gitignore
│ ├── package-lock.json
│ ├── package.json
│ ├── src
│ │ └── index.ts
│ └── tsconfig.json
├── package-lock.json
├── package.json
├── public
│ └── favicon.ico
├── seed
│ ├── auth_export
│ │ ├── accounts.json
│ │ └── config.json
│ ├── database_export
│ │ └── angularfire2-test.json
│ ├── firebase-export-metadata.json
│ ├── firestore_export
│ │ ├── all_namespaces
│ │ │ └── all_kinds
│ │ │ │ ├── all_namespaces_all_kinds.export_metadata
│ │ │ │ └── output-0
│ │ └── firestore_export.overall_export_metadata
│ └── storage_export
│ │ ├── blobs
│ │ └── angularfire2-test.appspot.com
│ │ │ └── google-g.png
│ │ ├── buckets.json
│ │ └── metadata
│ │ └── angularfire2-test.appspot.com
│ │ └── google-g.png.json
├── src
│ ├── app
│ │ ├── app.component.spec.ts
│ │ ├── app.component.ts
│ │ ├── app.config.client.ts
│ │ ├── app.config.server.ts
│ │ ├── app.config.ts
│ │ ├── app.routes.server.ts
│ │ ├── app.routes.ts
│ │ ├── auth
│ │ │ └── auth.component.ts
│ │ ├── database
│ │ │ └── database.component.ts
│ │ ├── firestore
│ │ │ └── firestore.component.ts
│ │ ├── functions
│ │ │ └── functions.component.ts
│ │ ├── messaging
│ │ │ └── messaging.component.ts
│ │ ├── remote-config
│ │ │ └── remote-config.component.ts
│ │ ├── storage
│ │ │ └── storage.component.ts
│ │ └── upboats
│ │ │ └── upboats.component.ts
│ ├── environments
│ │ └── environment.ts
│ ├── index.html
│ ├── main.server.ts
│ ├── main.ts
│ ├── server.ts
│ └── styles.css
├── storage.rules
├── tsconfig.app.json
├── tsconfig.json
└── tsconfig.spec.json
├── site
├── .eleventy.js
├── .firebaserc
├── .gitignore
├── firebase.json
├── package.json
├── postcss.config.js
├── scripts
│ └── build.js
└── src
│ ├── _data
│ └── nextprev.json
│ ├── _includes
│ ├── default.njk
│ ├── guide.njk
│ ├── next-prev.njk
│ └── side-nav.njk
│ ├── analytics
│ ├── analytics.11tydata.json
│ ├── getting-started.md
│ └── index.md
│ ├── assets
│ ├── GoogleSans-Bold.woff2
│ ├── GoogleSans-Medium.woff2
│ ├── GoogleSans-Regular.woff2
│ ├── Roboto-900.woff2
│ ├── Roboto-Italic.woff2
│ ├── Roboto-Regular.woff2
│ ├── RobotoMono-Regular.woff2
│ ├── corner.svg
│ └── firebase-logo.svg
│ ├── auth
│ ├── auth.11tydata.json
│ ├── getting-started.md
│ ├── index.md
│ └── route-guards.md
│ ├── favicon.ico
│ ├── firestore
│ ├── collections.md
│ ├── documents.md
│ ├── firestore.11tydata.json
│ └── index.md
│ ├── functions
│ ├── functions.11tydata.json
│ ├── getting-started.md
│ └── index.md
│ ├── get-started
│ ├── deploying.md
│ ├── get-started.11tydata.json
│ ├── index.md
│ ├── local-development.md
│ └── quick-start.md
│ ├── index.md
│ ├── ionic
│ ├── authentication.md
│ ├── getting-started.md
│ ├── index.md
│ └── ionic.11tydata.json
│ ├── js
│ ├── click-card.js
│ ├── menu-button.js
│ └── tab-switcher.js
│ ├── messaging
│ ├── getting-started.md
│ ├── index.md
│ └── messaging.11tydata.json
│ ├── performance
│ ├── getting-started.md
│ ├── index.md
│ └── performance.11tydata.json
│ ├── remote-config
│ ├── getting-started.md
│ ├── index.md
│ └── remote-config.11tydata.json
│ ├── rtdb
│ ├── index.md
│ ├── lists.md
│ ├── objects.md
│ ├── querying.md
│ └── rtdb.11tydata.json
│ ├── shortcodes
│ ├── buttons
│ │ └── index.js
│ ├── disclaimerprod
│ │ └── index.js
│ ├── filters
│ │ └── index.js
│ ├── headings
│ │ └── index.js
│ ├── includecode
│ │ ├── fetch.js
│ │ ├── from-local.js
│ │ ├── index.js
│ │ ├── snippets.js
│ │ └── transform.js
│ ├── index.js
│ └── version
│ │ └── index.js
│ ├── storage
│ ├── getting-started.md
│ ├── index.md
│ └── storage.11tydata.json
│ ├── styles
│ ├── prism.css
│ ├── tailwind.config.js
│ └── tailwind.css
│ └── universal
│ ├── cloud-functions.md
│ ├── getting-started.md
│ ├── index.md
│ ├── prerendering.md
│ └── universal.11tydata.json
├── src
├── ai
│ ├── ai.module.ts
│ ├── ai.spec.ts
│ ├── ai.ts
│ ├── firebase.ts
│ ├── ng-package.json
│ ├── package.json
│ └── public_api.ts
├── analytics
│ ├── analytics.module.ts
│ ├── analytics.spec.ts
│ ├── analytics.ts
│ ├── firebase.ts
│ ├── ng-package.json
│ ├── package.json
│ ├── public_api.ts
│ ├── screen-tracking.service.ts
│ └── user-tracking.service.ts
├── app-check
│ ├── app-check.module.ts
│ ├── app-check.spec.ts
│ ├── app-check.ts
│ ├── firebase.ts
│ ├── ng-package.json
│ ├── package.json
│ └── public_api.ts
├── app
│ ├── app.module.ts
│ ├── app.spec.ts
│ ├── app.ts
│ ├── firebase.ts
│ ├── ng-package.json
│ ├── package.json
│ └── public_api.ts
├── auth-guard
│ ├── auth-guard.module.ts
│ ├── auth-guard.spec.ts
│ ├── auth-guard.ts
│ ├── ng-package.json
│ ├── package.json
│ └── public_api.ts
├── auth
│ ├── auth.module.ts
│ ├── auth.spec.ts
│ ├── auth.ts
│ ├── firebase.ts
│ ├── ng-package.json
│ ├── package.json
│ ├── public_api.ts
│ └── rxfire.ts
├── compat
│ ├── analytics
│ │ ├── analytics.module.ts
│ │ ├── analytics.spec.ts
│ │ ├── analytics.ts
│ │ ├── base.ts
│ │ ├── index.ts
│ │ ├── ng-package.json
│ │ ├── package.json
│ │ ├── public_api.ts
│ │ ├── screen-tracking.service.ts
│ │ └── user-tracking.service.ts
│ ├── angularfire2.spec.ts
│ ├── auth-guard
│ │ ├── auth-guard.module.ts
│ │ ├── auth-guard.spec.ts
│ │ ├── auth-guard.ts
│ │ ├── ng-package.json
│ │ ├── package.json
│ │ └── public_api.ts
│ ├── auth
│ │ ├── auth.module.ts
│ │ ├── auth.spec.ts
│ │ ├── auth.ts
│ │ ├── base.ts
│ │ ├── ng-package.json
│ │ ├── package.json
│ │ └── public_api.ts
│ ├── cache.ts
│ ├── database
│ │ ├── database.module.ts
│ │ ├── database.spec.ts
│ │ ├── database.ts
│ │ ├── interfaces.ts
│ │ ├── list
│ │ │ ├── audit-trail.spec.ts
│ │ │ ├── audit-trail.ts
│ │ │ ├── changes.spec.ts
│ │ │ ├── changes.ts
│ │ │ ├── create-reference.ts
│ │ │ ├── data-operation.ts
│ │ │ ├── remove.ts
│ │ │ ├── snapshot-changes.spec.ts
│ │ │ ├── snapshot-changes.ts
│ │ │ ├── state-changes.spec.ts
│ │ │ ├── state-changes.ts
│ │ │ └── utils.ts
│ │ ├── ng-package.json
│ │ ├── object
│ │ │ ├── create-reference.ts
│ │ │ └── snapshot-changes.ts
│ │ ├── observable
│ │ │ ├── fromRef.spec.ts
│ │ │ └── fromRef.ts
│ │ ├── package.json
│ │ ├── public_api.ts
│ │ ├── utils.spec.ts
│ │ └── utils.ts
│ ├── firebase.app.module.ts
│ ├── firebase.app.ts
│ ├── firestore
│ │ ├── collection-group
│ │ │ ├── collection-group.spec.ts
│ │ │ └── collection-group.ts
│ │ ├── collection
│ │ │ ├── changes.ts
│ │ │ ├── collection.spec.ts
│ │ │ └── collection.ts
│ │ ├── document
│ │ │ ├── document.spec.ts
│ │ │ └── document.ts
│ │ ├── firestore.module.ts
│ │ ├── firestore.spec.ts
│ │ ├── firestore.ts
│ │ ├── interfaces.ts
│ │ ├── ng-package.json
│ │ ├── observable
│ │ │ └── fromRef.ts
│ │ ├── package.json
│ │ ├── public_api.ts
│ │ └── utils.spec.ts
│ ├── functions
│ │ ├── base.ts
│ │ ├── functions.module.ts
│ │ ├── functions.spec.ts
│ │ ├── functions.ts
│ │ ├── ng-package.json
│ │ ├── package.json
│ │ └── public_api.ts
│ ├── messaging
│ │ ├── base.ts
│ │ ├── messaging.module.ts
│ │ ├── messaging.spec.ts
│ │ ├── messaging.ts
│ │ ├── ng-package.json
│ │ ├── package.json
│ │ └── public_api.ts
│ ├── ng-package.json
│ ├── package.json
│ ├── performance
│ │ ├── base.ts
│ │ ├── ng-package.json
│ │ ├── package.json
│ │ ├── performance.module.ts
│ │ ├── performance.service.ts
│ │ ├── performance.spec.ts
│ │ ├── performance.ts
│ │ └── public_api.ts
│ ├── proxy.ts
│ ├── public_api.ts
│ ├── remote-config
│ │ ├── base.ts
│ │ ├── index.ts
│ │ ├── interfaces.ts
│ │ ├── ng-package.json
│ │ ├── package.json
│ │ ├── public_api.ts
│ │ ├── remote-config.module.ts
│ │ ├── remote-config.spec.ts
│ │ └── remote-config.ts
│ └── storage
│ │ ├── interfaces.ts
│ │ ├── ng-package.json
│ │ ├── observable
│ │ └── fromTask.ts
│ │ ├── package.json
│ │ ├── pipes
│ │ └── storageUrl.pipe.ts
│ │ ├── public_api.ts
│ │ ├── ref.ts
│ │ ├── storage.module.ts
│ │ ├── storage.spec.ts
│ │ ├── storage.ts
│ │ └── task.ts
├── core.ts
├── data-connect
│ ├── data-connect.module.ts
│ ├── data-connect.spec.ts
│ ├── data-connect.ts
│ ├── firebase.ts
│ ├── ng-package.json
│ ├── overrides.ts
│ ├── package.json
│ └── public_api.ts
├── database
│ ├── database.module.ts
│ ├── database.spec.ts
│ ├── database.ts
│ ├── firebase.ts
│ ├── ng-package.json
│ ├── package.json
│ ├── public_api.ts
│ └── rxfire.ts
├── firestore
│ ├── firebase.ts
│ ├── firestore.module.ts
│ ├── firestore.spec.ts
│ ├── firestore.ts
│ ├── lite
│ │ ├── firebase.ts
│ │ ├── lite.module.ts
│ │ ├── lite.spec.ts
│ │ ├── lite.ts
│ │ ├── ng-package.json
│ │ ├── package.json
│ │ ├── public_api.ts
│ │ └── rxfire.ts
│ ├── ng-package.json
│ ├── package.json
│ ├── public_api.ts
│ └── rxfire.ts
├── functions
│ ├── firebase.ts
│ ├── functions.module.ts
│ ├── functions.spec.ts
│ ├── functions.ts
│ ├── ng-package.json
│ ├── package.json
│ ├── public_api.ts
│ └── rxfire.ts
├── messaging
│ ├── firebase.ts
│ ├── messaging.module.ts
│ ├── messaging.spec.ts
│ ├── messaging.ts
│ ├── ng-package.json
│ ├── package.json
│ └── public_api.ts
├── ng-package.json
├── package.json
├── performance
│ ├── firebase.ts
│ ├── ng-package.json
│ ├── package.json
│ ├── performance.module.ts
│ ├── performance.spec.ts
│ ├── performance.ts
│ ├── public_api.ts
│ └── rxfire.ts
├── public_api.ts
├── remote-config
│ ├── firebase.ts
│ ├── ng-package.json
│ ├── package.json
│ ├── public_api.ts
│ ├── remote-config.module.ts
│ ├── remote-config.spec.ts
│ ├── remote-config.ts
│ └── rxfire.ts
├── schematics
│ ├── add
│ │ ├── index.ts
│ │ └── schema.json
│ ├── builders.json
│ ├── collection.json
│ ├── common.ts
│ ├── deploy
│ │ ├── actions.jasmine.ts
│ │ ├── actions.ts
│ │ ├── builder.ts
│ │ ├── functions-templates.ts
│ │ └── schema.json
│ ├── firebaseTools.ts
│ ├── interfaces.ts
│ ├── migration.json
│ ├── setup
│ │ ├── index.ts
│ │ ├── prompts.ts
│ │ └── schema.json
│ ├── tsconfig.json
│ ├── update
│ │ ├── index.ts
│ │ └── v7
│ │ │ └── index.ts
│ ├── utils.ts
│ └── versions.json
├── storage
│ ├── firebase.ts
│ ├── ng-package.json
│ ├── package.json
│ ├── public_api.ts
│ ├── rxfire.ts
│ ├── storage.module.ts
│ ├── storage.spec.ts
│ └── storage.ts
├── test-config.ts
├── test.ts
├── utils.ts
├── vertexai
│ ├── firebase.ts
│ ├── ng-package.json
│ ├── package.json
│ ├── public_api.ts
│ ├── vertexai.module.ts
│ ├── vertexai.spec.ts
│ └── vertexai.ts
└── zones.ts
├── test
├── database.rules.json
├── firestore.indexes.json
├── firestore.rules
├── functions
│ ├── .gitignore
│ ├── package-lock.json
│ ├── package.json
│ ├── src
│ │ └── index.ts
│ └── tsconfig.json
└── storage.rules
├── tools
├── build.sh
├── build.ts
└── jasmine.ts
├── tsconfig.base.json
├── tsconfig.build.json
├── tsconfig.jasmine.json
├── tsconfig.json
├── tsconfig.spec.json
└── typedoc.json
/.editorconfig:
--------------------------------------------------------------------------------
1 | # http://editorconfig.org
2 |
3 | root = true
4 |
5 | [*]
6 | charset = utf-8
7 | indent_style = space
8 | indent_size = 2
9 | end_of_line = lf
10 | insert_final_newline = true
11 | trim_trailing_whitespace = true
12 |
13 | [*.md]
14 | insert_final_newline = false
15 | trim_trailing_whitespace = false
16 |
--------------------------------------------------------------------------------
/.firebaserc:
--------------------------------------------------------------------------------
1 | {
2 | "projects": {
3 | "default": "angularfire2-test"
4 | }
5 | }
6 |
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | src/**/firebase.ts linguist-generated=true
2 | src/**/rxfire.ts linguist-generated=true
3 | src/compat/**/base.ts linguist-generated=true
4 | samples/**/* linguist-generated=true
5 | yarn.lock linguist-generated=true
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules/
2 | dist/
3 | dist-test/
4 | docs/api/
5 | typings/
6 | npm-debug.log
7 | .idea/
8 | .vscode/settings.json
9 | angular-fire-*.tgz
10 | angularfire2-*.tgz
11 | *.ngfactory.ts
12 | *.ngsummary.json
13 | .DS_Store
14 | yarn-error.log
15 | *.bak
16 | yarn.lock
17 | test/ng-build/**/yarn.lock
18 | tools/build.js
19 | coverage
20 | *.log
21 | api-*.json
22 | angularfire.tgz
23 | unpack.sh
24 | publish.sh
25 | .firebase
26 | .angular
27 | .vscode
--------------------------------------------------------------------------------
/.npmignore:
--------------------------------------------------------------------------------
1 | *.spec.*
2 | test-config.*
3 | publish.sh
4 | __ivy_ngcc__/
5 | *.min.js
6 | *.min.js.map
7 | *.__ivy_ngcc_bak
--------------------------------------------------------------------------------
/.nvmrc:
--------------------------------------------------------------------------------
1 | lts/*
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License
2 |
3 | Copyright (c) 2014-2016 Google, Inc. http://angular.io
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in
13 | all copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 | THE SOFTWARE.
22 |
--------------------------------------------------------------------------------
/PULL_REQUEST_TEMPLATE.md:
--------------------------------------------------------------------------------
1 |
22 |
23 | ### Checklist
24 |
25 | - Issue number for this PR: #nnn (required)
26 | - Docs included?: (yes/no; required for all API/functional changes)
27 | - Test units included?: (yes/no; required)
28 | - In a clean directory, `yarn install`, `yarn test` run successfully? (yes/no; required)
29 |
30 | ### Description
31 |
32 |
34 |
35 | ### Code sample
36 |
37 |
38 |
39 |
--------------------------------------------------------------------------------
/SECURITY.md:
--------------------------------------------------------------------------------
1 | # Security Policy
2 |
3 | ## Supported Versions
4 |
5 | | Version | Supported |
6 | | ------- | ------------------ |
7 | | 6.0+ | :white_check_mark: |
8 | | < 6.0 | :x: |
9 |
10 | ## Reporting a Vulnerability
11 |
12 | Please contact [Firebase support](https://firebase.google.com/support) and send ticket details to [angularfire-maintainers@google.com](mailto:angularfire-maintainers@google.com?subject=[SECURITY]) with `[SECURITY]` in the subject.
13 |
--------------------------------------------------------------------------------
/angular.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "./node_modules/@angular/cli/lib/config/schema.json",
3 | "version": 1,
4 | "newProjectRoot": ".",
5 | "projects": {
6 | "angularfire": {
7 | "projectType": "library",
8 | "root": "src",
9 | "sourceRoot": "src",
10 | "prefix": "angularfire",
11 | "architect": {
12 | "build": {
13 | "builder": "@angular-devkit/build-angular:ng-packagr",
14 | "options": {
15 | "tsConfig": "tsconfig.json",
16 | "project": "src/ng-package.json"
17 | }
18 | },
19 | "test": {
20 | "builder": "@angular-devkit/build-angular:karma",
21 | "options": {
22 | "polyfills": [
23 | "zone.js",
24 | "zone.js/testing"
25 | ],
26 | "tsConfig": "tsconfig.spec.json",
27 | "karmaConfig": "karma.conf.js"
28 | }
29 | },
30 | "lint": {
31 | "builder": "@angular-eslint/builder:lint",
32 | "options": {
33 | "lintFilePatterns": [
34 | "src/**/*.ts",
35 | "src/**/*.html"
36 | ]
37 | }
38 | }
39 | }
40 | }
41 | },
42 | "cli": {
43 | "packageManager": "npm",
44 | "analytics": "86795b8f-9036-4a53-929c-a7303453d677"
45 | }
46 | }
--------------------------------------------------------------------------------
/docs/firebase.json:
--------------------------------------------------------------------------------
1 | {
2 | "firebase": "angular-fire-2",
3 | "public": ".",
4 | "redirects": [
5 | {
6 | "source": "/",
7 | "destination": "/api",
8 | "type": 302
9 | }
10 | ],
11 | "ignore": [
12 | "firebase.json",
13 | "**/.*",
14 | "**/node_modules/**"
15 | ]
16 | }
17 |
--------------------------------------------------------------------------------
/docs/images/analytics-illo_1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/angular/angularfire/c1c6af9779154caff6bc0d9b837f6c3e2d913456/docs/images/analytics-illo_1x.png
--------------------------------------------------------------------------------
/docs/images/auth-illo_1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/angular/angularfire/c1c6af9779154caff6bc0d9b837f6c3e2d913456/docs/images/auth-illo_1x.png
--------------------------------------------------------------------------------
/docs/images/cloud-messaging-illo_1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/angular/angularfire/c1c6af9779154caff6bc0d9b837f6c3e2d913456/docs/images/cloud-messaging-illo_1x.png
--------------------------------------------------------------------------------
/docs/images/database-illo_1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/angular/angularfire/c1c6af9779154caff6bc0d9b837f6c3e2d913456/docs/images/database-illo_1x.png
--------------------------------------------------------------------------------
/docs/images/firestore-illo_1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/angular/angularfire/c1c6af9779154caff6bc0d9b837f6c3e2d913456/docs/images/firestore-illo_1x.png
--------------------------------------------------------------------------------
/docs/images/functions-illo_1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/angular/angularfire/c1c6af9779154caff6bc0d9b837f6c3e2d913456/docs/images/functions-illo_1x.png
--------------------------------------------------------------------------------
/docs/images/hosting-illo_1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/angular/angularfire/c1c6af9779154caff6bc0d9b837f6c3e2d913456/docs/images/hosting-illo_1x.png
--------------------------------------------------------------------------------
/docs/images/performance-illo_1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/angular/angularfire/c1c6af9779154caff6bc0d9b837f6c3e2d913456/docs/images/performance-illo_1x.png
--------------------------------------------------------------------------------
/docs/images/reCAPTCHA-logo@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/angular/angularfire/c1c6af9779154caff6bc0d9b837f6c3e2d913456/docs/images/reCAPTCHA-logo@1x.png
--------------------------------------------------------------------------------
/docs/images/remote-config-illo_1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/angular/angularfire/c1c6af9779154caff6bc0d9b837f6c3e2d913456/docs/images/remote-config-illo_1x.png
--------------------------------------------------------------------------------
/docs/images/storage-illo_1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/angular/angularfire/c1c6af9779154caff6bc0d9b837f6c3e2d913456/docs/images/storage-illo_1x.png
--------------------------------------------------------------------------------
/docs/universal/getting-started.md:
--------------------------------------------------------------------------------
1 | # Getting started with AngularFire and Universal
2 |
3 | Server-side rendering (SSR) is the process of converting a JavaScript app to plain HTML at request-time, allowing search engine crawlers and linkbots to understand page content reliably.
4 |
5 | ## 0. Prerequisites
6 |
7 | - @angular/cli >= v6.0
8 | - @angular/fire >= v5.0.0
9 |
10 | ## 1. Add Angular Universal to your project
11 |
12 | Follow the steps from the [Angular Universal Tutorial](https://angular.io/guide/universal) to add Universal to your
13 | project.
14 |
15 | ```
16 | ng add @nguniversal/express-engine
17 | ```
18 |
19 | This will create all the files you need and setup all the configurations for Universal rendering for your application.
20 |
21 | ## 2. Next Steps
22 |
23 | Test your app locally by running `npm run dev:ssr`.
24 |
25 | _Note: `dev:ssr` is a command that was added to your `package.json` by the `ng add` command that will run the dev server
26 | for your Angular with Universal._
27 |
28 | ### [Next Step: Deploying your Universal application on Cloud Functions for Firebase](cloud-functions.md)
29 |
--------------------------------------------------------------------------------
/docs/version-6-upgrade.md:
--------------------------------------------------------------------------------
1 | # Upgrading to AngularFire 6.0
2 |
3 | Intended to be run with Angular 9; version 6 of AngularFire drops support for Angular version 8 and below, older versions of typescript, Firebase, drops `firebase-node`, `database-deprecated`, and more.
4 |
5 | ## Breaking changes:
6 |
7 | * Support for Angular versions less than 9 has been dropped
8 | * Support for Firebase JS SDK versions less than 7.13.1 has been dropped
9 | * Support for `firebase-tools` less than 8.0 has been dropped
10 | * The `angularfire2` NPM library will no longer be updated
11 | * Dropped `@angular/fire/firebase-node` and `@angular/fire/database-depreciated`
12 | * We make use of Proxy in more modules, you'll need to polyfill if you want to support IE 11
13 | * We've standardized our DI Token naming conventions across all modules
14 | * `AngularFireAuth` has dropped the `auth` property and instead Promise Proxies the underlying Firebase `auth.Auth` instance; allowing your development experience to more closely mirror the JS SDK. Similar changes have been made to `AngularFireFunctions`, `AngularFireMessaging`, and `AngularFirePerformance`.
15 | * `AngularFireAuthGuard` and `canActivate` have dropped support for raw pipes, this was never working correctly in AOT
16 | * `AngularFirePerformance` has been simplified, the RXJS pipes are now exported as pure-functions outside the class. Automatic tracking of `isStable` timing has now been moved into `PerformanceMonitoringService` and we've dropped the `AUTOMATICALLY_TRACE_CORE_NG_METRICS` DI token.
--------------------------------------------------------------------------------
/firebase.json:
--------------------------------------------------------------------------------
1 | {
2 | "database": {
3 | "rules": "test/database.rules.json"
4 | },
5 | "firestore": {
6 | "rules": "test/firestore.rules",
7 | "indexes": "test/firestore.indexes.json"
8 | },
9 | "storage": {
10 | "rules": "test/storage.rules"
11 | },
12 | "emulators": {
13 | "auth": {
14 | "port": 9098
15 | },
16 | "functions": {
17 | "port": 5001
18 | },
19 | "firestore": {
20 | "port": 8089
21 | },
22 | "database": {
23 | "port": 9002
24 | },
25 | "storage": {
26 | "port": 9199
27 | },
28 | "ui": {
29 | "enabled": false
30 | }
31 | },
32 | "functions": [
33 | {
34 | "source": "test/functions",
35 | "codebase": "default",
36 | "ignore": [
37 | "node_modules",
38 | ".git",
39 | "firebase-debug.log",
40 | "firebase-debug.*.log",
41 | "*.local"
42 | ],
43 | "predeploy": [
44 | "npm --prefix \"$RESOURCE_DIR\" run build"
45 | ]
46 | }
47 | ]
48 | }
49 |
--------------------------------------------------------------------------------
/sample/.editorconfig:
--------------------------------------------------------------------------------
1 | # Editor configuration, see https://editorconfig.org
2 | root = true
3 |
4 | [*]
5 | charset = utf-8
6 | indent_style = space
7 | indent_size = 2
8 | insert_final_newline = true
9 | trim_trailing_whitespace = true
10 |
11 | [*.ts]
12 | quote_type = single
13 | ij_typescript_use_double_quotes = false
14 |
15 | [*.md]
16 | max_line_length = off
17 | trim_trailing_whitespace = false
18 |
--------------------------------------------------------------------------------
/sample/.firebaserc:
--------------------------------------------------------------------------------
1 | {
2 | "projects": {
3 | "default": "angularfire2-test"
4 | }
5 | }
6 |
--------------------------------------------------------------------------------
/sample/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://docs.github.com/get-started/getting-started-with-git/ignoring-files for more about ignoring files.
2 |
3 | # Compiled output
4 | /dist
5 | /tmp
6 | /out-tsc
7 | /bazel-out
8 |
9 | # Node
10 | /node_modules
11 | npm-debug.log
12 | yarn-error.log
13 |
14 | # IDEs and editors
15 | .idea/
16 | .project
17 | .classpath
18 | .c9/
19 | *.launch
20 | .settings/
21 | *.sublime-workspace
22 |
23 | # Visual Studio Code
24 | .vscode/*
25 | !.vscode/settings.json
26 | !.vscode/tasks.json
27 | !.vscode/launch.json
28 | !.vscode/extensions.json
29 | .history/*
30 |
31 | # Miscellaneous
32 | /.angular/cache
33 | .sass-cache/
34 | /connect.lock
35 | /coverage
36 | /libpeerconnection.log
37 | testem.log
38 | /typings
39 |
40 | # System files
41 | .DS_Store
42 | Thumbs.db
43 |
44 | # Firebase
45 | .firebase
46 | *-debug.log
47 | .runtimeconfig.json
48 |
--------------------------------------------------------------------------------
/sample/README.md:
--------------------------------------------------------------------------------
1 | # Ng19Test
2 |
3 | This project was generated using [Angular CLI](https://github.com/angular/angular-cli) version 19.0.0.
4 |
5 | ## Development server
6 |
7 | To start a local development server, run:
8 |
9 | ```bash
10 | ng serve
11 | ```
12 |
13 | Once the server is running, open your browser and navigate to `http://localhost:4200/`. The application will automatically reload whenever you modify any of the source files.
14 |
15 | ## Code scaffolding
16 |
17 | Angular CLI includes powerful code scaffolding tools. To generate a new component, run:
18 |
19 | ```bash
20 | ng generate component component-name
21 | ```
22 |
23 | For a complete list of available schematics (such as `components`, `directives`, or `pipes`), run:
24 |
25 | ```bash
26 | ng generate --help
27 | ```
28 |
29 | ## Building
30 |
31 | To build the project run:
32 |
33 | ```bash
34 | ng build
35 | ```
36 |
37 | This will compile your project and store the build artifacts in the `dist/` directory. By default, the production build optimizes your application for performance and speed.
38 |
39 | ## Running unit tests
40 |
41 | To execute unit tests with the [Karma](https://karma-runner.github.io) test runner, use the following command:
42 |
43 | ```bash
44 | ng test
45 | ```
46 |
47 | ## Running end-to-end tests
48 |
49 | For end-to-end (e2e) testing, run:
50 |
51 | ```bash
52 | ng e2e
53 | ```
54 |
55 | Angular CLI does not come with an end-to-end testing framework by default. You can choose one that suits your needs.
56 |
57 | ## Additional Resources
58 |
59 | For more information on using the Angular CLI, including detailed command references, visit the [Angular CLI Overview and Command Reference](https://angular.dev/tools/cli) page.
60 |
--------------------------------------------------------------------------------
/sample/database.rules.json:
--------------------------------------------------------------------------------
1 | {
2 | /* Visit https://firebase.google.com/docs/database/security to learn more about security rules. */
3 | "rules": {
4 | ".read": true,
5 | ".write": false
6 | }
7 | }
--------------------------------------------------------------------------------
/sample/firebase.json:
--------------------------------------------------------------------------------
1 | {
2 | "database": {
3 | "rules": "database.rules.json"
4 | },
5 | "firestore": {
6 | "rules": "firestore.rules",
7 | "indexes": "firestore.indexes.json"
8 | },
9 | "storage": {
10 | "rules": "storage.rules"
11 | },
12 | "functions": [
13 | {
14 | "source": "functions",
15 | "codebase": "default",
16 | "ignore": [
17 | "node_modules",
18 | ".git",
19 | "firebase-debug.log",
20 | "firebase-debug.*.log"
21 | ],
22 | "predeploy": [
23 | "npm --prefix \"$RESOURCE_DIR\" run build"
24 | ]
25 | }
26 | ],
27 | "emulators": {
28 | "auth": {
29 | "port": 9099
30 | },
31 | "functions": {
32 | "port": 5001
33 | },
34 | "firestore": {
35 | "port": 8080
36 | },
37 | "database": {
38 | "port": 9000
39 | },
40 | "storage": {
41 | "port": 9199
42 | },
43 | "ui": {
44 | "enabled": true
45 | }
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/sample/firestore.indexes.json:
--------------------------------------------------------------------------------
1 | {
2 | "indexes": [
3 | {
4 | "collectionGroup": "animals",
5 | "queryScope": "COLLECTION",
6 | "fields": [
7 | {
8 | "fieldPath": "upboats",
9 | "order": "DESCENDING"
10 | },
11 | {
12 | "fieldPath": "updatedAt",
13 | "order": "DESCENDING"
14 | }
15 | ]
16 | }
17 | ],
18 | "fieldOverrides": []
19 | }
20 |
--------------------------------------------------------------------------------
/sample/firestore.rules:
--------------------------------------------------------------------------------
1 | service cloud.firestore {
2 | match /databases/{database}/documents {
3 | match /{document=**} {
4 | allow read;
5 | allow write: if false;
6 | }
7 | match /animals/{document=**} {
8 | allow read;
9 | allow write: if request.auth != null;
10 | }
11 | match /dreams/{document=**} {
12 | allow read;
13 | allow write;
14 | }
15 | }
16 | }
--------------------------------------------------------------------------------
/sample/functions/.gitignore:
--------------------------------------------------------------------------------
1 | # Compiled JavaScript files
2 | **/*.js
3 | **/*.js.map
4 |
5 | # Except the ESLint config file
6 | !.eslintrc.js
7 |
8 | # TypeScript v1 declaration files
9 | typings/
10 |
11 | # Node.js dependency directory
12 | node_modules/
13 | lib/
14 |
--------------------------------------------------------------------------------
/sample/functions/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "functions",
3 | "scripts": {
4 | "build": "tsc",
5 | "serve": "npm run build && firebase emulators:start --only functions",
6 | "shell": "npm run build && firebase functions:shell",
7 | "start": "npm run shell",
8 | "deploy": "firebase deploy --only functions",
9 | "logs": "firebase functions:log"
10 | },
11 | "engines": {
12 | "node": "20"
13 | },
14 | "main": "lib/index.js",
15 | "dependencies": {
16 | "firebase-admin": "^13.0.1",
17 | "firebase-functions": "^6.1.2"
18 | },
19 | "devDependencies": {
20 | "typescript": "^5.7.2"
21 | },
22 | "private": true
23 | }
24 |
--------------------------------------------------------------------------------
/sample/functions/src/index.ts:
--------------------------------------------------------------------------------
1 | import { onCall } from "firebase-functions/https";
2 |
3 | export const yada = onCall(() => {
4 | return { time: new Date().getTime() };
5 | });
6 |
--------------------------------------------------------------------------------
/sample/functions/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "module": "commonjs",
4 | "noImplicitReturns": true,
5 | "noUnusedLocals": true,
6 | "outDir": "lib",
7 | "sourceMap": true,
8 | "strict": true,
9 | "target": "es2020"
10 | },
11 | "compileOnSave": true,
12 | "include": [
13 | "src"
14 | ]
15 | }
16 |
--------------------------------------------------------------------------------
/sample/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "ng19-test",
3 | "version": "0.0.0",
4 | "scripts": {
5 | "ng": "ng",
6 | "start": "firebase emulators:exec --import seed \"ng serve\"",
7 | "build": "ng build",
8 | "watch": "ng build --watch --configuration development",
9 | "test": "ng test",
10 | "serve:ssr:ng19-test": "node dist/ng19-test/server/server.mjs"
11 | },
12 | "private": true,
13 | "dependencies": {
14 | "@angular/animations": "^19.0.0",
15 | "@angular/common": "^19.0.0",
16 | "@angular/compiler": "^19.0.0",
17 | "@angular/core": "^19.0.0",
18 | "@angular/fire": "file:../angular-fire-19.0.0.tgz",
19 | "@angular/forms": "^19.0.0",
20 | "@angular/platform-browser": "^19.0.0",
21 | "@angular/platform-browser-dynamic": "^19.0.0",
22 | "@angular/platform-server": "^19.0.0",
23 | "@angular/router": "^19.0.0",
24 | "@angular/ssr": "^19.0.0",
25 | "cookie-parser": "^1.4.7",
26 | "cookie-store": "^4.0.0-next.4",
27 | "express": "^4.18.2",
28 | "firebase-admin": "^13.0.1",
29 | "js-cookie": "^3.0.5",
30 | "rxjs": "~7.8.0",
31 | "tslib": "^2.3.0",
32 | "zone.js": "~0.15.0"
33 | },
34 | "devDependencies": {
35 | "@angular-devkit/build-angular": "^19.0.0",
36 | "@angular/cli": "^19.0.0",
37 | "@angular/compiler-cli": "^19.0.0",
38 | "@types/cookie-parser": "^1.4.8",
39 | "@types/express": "^4.17.17",
40 | "@types/jasmine": "~5.1.0",
41 | "@types/js-cookie": "^3.0.6",
42 | "@types/node": "^18.18.0",
43 | "jasmine-core": "~5.4.0",
44 | "karma": "~6.4.0",
45 | "karma-chrome-launcher": "~3.2.0",
46 | "karma-coverage": "~2.2.0",
47 | "karma-jasmine": "~5.1.0",
48 | "karma-jasmine-html-reporter": "~2.1.0",
49 | "typescript": "~5.6.2"
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/sample/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/angular/angularfire/c1c6af9779154caff6bc0d9b837f6c3e2d913456/sample/public/favicon.ico
--------------------------------------------------------------------------------
/sample/seed/auth_export/accounts.json:
--------------------------------------------------------------------------------
1 | {"kind":"identitytoolkit#DownloadAccountResponse","users":[]}
--------------------------------------------------------------------------------
/sample/seed/auth_export/config.json:
--------------------------------------------------------------------------------
1 | {"signIn":{"allowDuplicateEmails":false}}
--------------------------------------------------------------------------------
/sample/seed/database_export/angularfire2-test.json:
--------------------------------------------------------------------------------
1 | {"test":{"foo":"bar"}}
--------------------------------------------------------------------------------
/sample/seed/firebase-export-metadata.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": "9.18.0",
3 | "firestore": {
4 | "version": "1.13.1",
5 | "path": "firestore_export",
6 | "metadata_file": "firestore_export/firestore_export.overall_export_metadata"
7 | },
8 | "database": {
9 | "version": "4.7.2",
10 | "path": "database_export"
11 | },
12 | "auth": {
13 | "version": "9.18.0",
14 | "path": "auth_export"
15 | },
16 | "storage": {
17 | "version": "9.18.0",
18 | "path": "storage_export"
19 | }
20 | }
--------------------------------------------------------------------------------
/sample/seed/firestore_export/all_namespaces/all_kinds/all_namespaces_all_kinds.export_metadata:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/angular/angularfire/c1c6af9779154caff6bc0d9b837f6c3e2d913456/sample/seed/firestore_export/all_namespaces/all_kinds/all_namespaces_all_kinds.export_metadata
--------------------------------------------------------------------------------
/sample/seed/firestore_export/all_namespaces/all_kinds/output-0:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/angular/angularfire/c1c6af9779154caff6bc0d9b837f6c3e2d913456/sample/seed/firestore_export/all_namespaces/all_kinds/output-0
--------------------------------------------------------------------------------
/sample/seed/firestore_export/firestore_export.overall_export_metadata:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/angular/angularfire/c1c6af9779154caff6bc0d9b837f6c3e2d913456/sample/seed/firestore_export/firestore_export.overall_export_metadata
--------------------------------------------------------------------------------
/sample/seed/storage_export/blobs/angularfire2-test.appspot.com/google-g.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/angular/angularfire/c1c6af9779154caff6bc0d9b837f6c3e2d913456/sample/seed/storage_export/blobs/angularfire2-test.appspot.com/google-g.png
--------------------------------------------------------------------------------
/sample/seed/storage_export/buckets.json:
--------------------------------------------------------------------------------
1 | {
2 | "buckets": [
3 | {
4 | "id": "default-bucket"
5 | },
6 | {
7 | "id": "angularfire2-test.appspot.com"
8 | }
9 | ]
10 | }
11 |
--------------------------------------------------------------------------------
/sample/seed/storage_export/metadata/angularfire2-test.appspot.com/google-g.png.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "google-g.png",
3 | "bucket": "angularfire2-test.appspot.com",
4 | "contentType": "image/png",
5 | "metageneration": 1,
6 | "generation": 1631220526565,
7 | "storageClass": "STANDARD",
8 | "etag": "someETag",
9 | "contentDisposition": "inline",
10 | "contentEncoding": "identity",
11 | "downloadTokens": [
12 | "7553ce27-5bd0-409d-843b-25ff4d792740"
13 | ],
14 | "timeCreated": "2021-09-09T20:48:46.564Z",
15 | "updated": "2021-09-09T20:48:46.567Z",
16 | "size": 9916,
17 | "md5Hash": "3NH+6XyxOMx2hUhq9d4hxQ==",
18 | "crc32c": "2188947963"
19 | }
20 |
--------------------------------------------------------------------------------
/sample/src/app/app.component.spec.ts:
--------------------------------------------------------------------------------
1 | import { TestBed } from '@angular/core/testing';
2 | import { AppComponent } from './app.component';
3 |
4 | describe('AppComponent', () => {
5 | beforeEach(async () => {
6 | await TestBed.configureTestingModule({
7 | imports: [AppComponent],
8 | }).compileComponents();
9 | });
10 |
11 | it('should create the app', () => {
12 | const fixture = TestBed.createComponent(AppComponent);
13 | const app = fixture.componentInstance;
14 | expect(app).toBeTruthy();
15 | });
16 |
17 | it(`should have the 'ng19-test' title`, () => {
18 | const fixture = TestBed.createComponent(AppComponent);
19 | const app = fixture.componentInstance;
20 | expect(app.title).toEqual('ng19-test');
21 | });
22 |
23 | it('should render title', () => {
24 | const fixture = TestBed.createComponent(AppComponent);
25 | fixture.detectChanges();
26 | const compiled = fixture.nativeElement as HTMLElement;
27 | expect(compiled.querySelector('h1')?.textContent).toContain('Hello, ng19-test');
28 | });
29 | });
30 |
--------------------------------------------------------------------------------
/sample/src/app/app.component.ts:
--------------------------------------------------------------------------------
1 | import { Component } from '@angular/core';
2 | import { RouterOutlet } from '@angular/router';
3 | import { AuthComponent } from './auth/auth.component';
4 | import { DatabaseComponent } from './database/database.component';
5 | import { FirestoreComponent } from './firestore/firestore.component';
6 | import { FunctionsComponent } from './functions/functions.component';
7 | import { MessagingComponent } from './messaging/messaging.component';
8 | import { RemoteConfigComponent } from './remote-config/remote-config.component';
9 | import { StorageComponent } from './storage/storage.component';
10 | import { UpboatsComponent } from './upboats/upboats.component';
11 |
12 | @Component({
13 | selector: 'app-root',
14 | imports: [
15 | RouterOutlet,
16 | AuthComponent,
17 | DatabaseComponent,
18 | FirestoreComponent,
19 | FunctionsComponent,
20 | MessagingComponent,
21 | RemoteConfigComponent,
22 | StorageComponent,
23 | UpboatsComponent
24 | ],
25 | template: `
26 | Hello World!
27 |
28 | @defer (hydrate on idle) { } @placeholder { Database! … }
29 | @defer (hydrate on idle) { } @placeholder { Firestore! … }
30 | @defer (hydrate on idle) { } @placeholder { Functions! … }
31 | @defer (hydrate on idle) { } @placeholder { Messaging! … }
32 | @defer (hydrate on idle) { } @placeholder { Remote Config! … }
33 | @defer (hydrate never) { } @placeholder { Storage! … }
34 | @defer (hydrate on idle) { } @placeholder { … }
35 |
36 | `,
37 | })
38 | export class AppComponent {
39 | title = 'ng19-test';
40 | }
41 |
--------------------------------------------------------------------------------
/sample/src/app/app.config.client.ts:
--------------------------------------------------------------------------------
1 | import { mergeApplicationConfig, ApplicationConfig } from '@angular/core';
2 | import { initializeApp, provideFirebaseApp } from '@angular/fire/app';
3 | import { getAnalytics, provideAnalytics, ScreenTrackingService, UserTrackingService } from '@angular/fire/analytics';
4 | import { getMessaging, provideMessaging } from '@angular/fire/messaging';
5 | import { getPerformance, providePerformance } from '@angular/fire/performance';
6 |
7 | import { appConfig } from './app.config';
8 |
9 | import { environment } from '../environments/environment';
10 |
11 | const clientConfig: ApplicationConfig = {
12 | providers: [
13 | provideFirebaseApp(() => initializeApp(environment.firebase)),
14 | provideAnalytics(() => getAnalytics()),
15 | ScreenTrackingService,
16 | UserTrackingService,
17 | provideMessaging(() => getMessaging()),
18 | providePerformance(() => getPerformance()),
19 | ]
20 | };
21 |
22 | export const config = mergeApplicationConfig(appConfig, clientConfig);
23 |
--------------------------------------------------------------------------------
/sample/src/app/app.config.server.ts:
--------------------------------------------------------------------------------
1 | import { mergeApplicationConfig, ApplicationConfig, inject, REQUEST_CONTEXT } from '@angular/core';
2 | import { initializeServerApp, provideFirebaseApp } from '@angular/fire/app';
3 | import { provideServerRendering } from '@angular/platform-server';
4 | import { provideServerRoutesConfig } from '@angular/ssr';
5 |
6 | import { appConfig } from './app.config';
7 | import { serverRoutes } from './app.routes.server';
8 | import { environment } from '../environments/environment';
9 |
10 | const serverConfig: ApplicationConfig = {
11 | providers: [
12 | provideServerRendering(),
13 | provideServerRoutesConfig(serverRoutes),
14 | provideFirebaseApp(() => {
15 | // TODO migrate to REQUEST once that's working
16 | const requestContext = inject(REQUEST_CONTEXT, { optional: true }) as {
17 | authIdToken: string,
18 | } | undefined;
19 | const authIdToken = requestContext?.authIdToken;
20 | return initializeServerApp(environment.firebase, { authIdToken });
21 | }),
22 | ]
23 | };
24 |
25 | export const config = mergeApplicationConfig(appConfig, serverConfig);
26 |
--------------------------------------------------------------------------------
/sample/src/app/app.config.ts:
--------------------------------------------------------------------------------
1 | import { ApplicationConfig, inject, provideExperimentalZonelessChangeDetection } from '@angular/core';
2 | import { connectAuthEmulator, getAuth, provideAuth } from '@angular/fire/auth';
3 | import { provideClientHydration, withIncrementalHydration } from '@angular/platform-browser';
4 | import { provideRouter } from '@angular/router';
5 |
6 | import { routes } from './app.routes';
7 | import { FirebaseApp } from '@angular/fire/app';
8 | import { environment } from '../environments/environment';
9 |
10 | export const appConfig: ApplicationConfig = {
11 | providers: [
12 | provideExperimentalZonelessChangeDetection(),
13 | provideRouter(routes),
14 | provideClientHydration(withIncrementalHydration()),
15 | provideAuth(() => {
16 | const auth = getAuth(inject(FirebaseApp));
17 | if ((auth as any)._canInitEmulator && environment.emulatorPorts?.auth) {
18 | connectAuthEmulator(auth, `http://localhost:${environment.emulatorPorts.auth}`, { disableWarnings: true });
19 | }
20 | return auth;
21 | }),
22 | ],
23 | };
24 |
--------------------------------------------------------------------------------
/sample/src/app/app.routes.server.ts:
--------------------------------------------------------------------------------
1 | import { RenderMode, ServerRoute } from '@angular/ssr';
2 |
3 | export const serverRoutes: ServerRoute[] = [
4 | {
5 | path: '**',
6 | renderMode: RenderMode.Server
7 | }
8 | ];
9 |
--------------------------------------------------------------------------------
/sample/src/app/app.routes.ts:
--------------------------------------------------------------------------------
1 | import { Routes } from '@angular/router';
2 |
3 | export const routes: Routes = [];
4 |
--------------------------------------------------------------------------------
/sample/src/app/database/database.component.ts:
--------------------------------------------------------------------------------
1 | import { Component, inject, makeStateKey, PLATFORM_ID, TransferState } from '@angular/core';
2 | import { startWith, tap } from 'rxjs';
3 | import { connectDatabaseEmulator, getDatabase, objectVal, ref } from '@angular/fire/database';
4 | import { AsyncPipe, isPlatformServer, JsonPipe } from '@angular/common';
5 | import { FirebaseApp } from '@angular/fire/app';
6 | import { environment } from '../../environments/environment';
7 |
8 | @Component({
9 | selector: 'app-database',
10 | template: `
11 |
12 | Database!
13 | {{ testObjectValue$ | async | json }}
14 |
15 | `,
16 | imports: [AsyncPipe, JsonPipe]
17 | })
18 | export class DatabaseComponent {
19 |
20 | private readonly database;
21 |
22 | private readonly transferState = inject(TransferState);
23 | private readonly transferStateKey = makeStateKey("database:test");
24 | protected readonly testObjectValue$;
25 |
26 | constructor() {
27 | this.database = getDatabase(inject(FirebaseApp));
28 | if (!(this.database as any)._instanceStarted && environment.emulatorPorts?.database) {
29 | connectDatabaseEmulator(this.database, "localhost", environment.emulatorPorts.database);
30 | }
31 |
32 | this.testObjectValue$ = objectVal(ref(this.database, "test")).pipe(
33 | isPlatformServer(inject(PLATFORM_ID)) ?
34 | tap(it => this.transferState.set(this.transferStateKey, it)) :
35 | this.transferState.hasKey(this.transferStateKey) ?
36 | startWith(this.transferState.get(this.transferStateKey, undefined)) :
37 | tap()
38 | );
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/sample/src/app/firestore/firestore.component.ts:
--------------------------------------------------------------------------------
1 | import { Component, inject, makeStateKey, PLATFORM_ID, signal, TransferState } from '@angular/core';
2 | import { traceUntilFirst } from '@angular/fire/performance';
3 | import { doc, docData, getFirestore, connectFirestoreEmulator } from '@angular/fire/firestore';
4 | import { startWith, tap } from 'rxjs';
5 | import { AsyncPipe, isPlatformServer, JsonPipe } from '@angular/common';
6 | import { FirebaseApp } from '@angular/fire/app';
7 | import { environment } from '../../environments/environment';
8 |
9 | @Component({
10 | selector: 'app-firestore',
11 | template: `
12 | Firestore!
13 | {{ testDocValue | async | json }}
14 |
`,
15 | imports: [ AsyncPipe, JsonPipe ]
16 | })
17 | export class FirestoreComponent {
18 |
19 | private readonly firestore;
20 |
21 | private readonly transferState = inject(TransferState);
22 | private readonly transferStateKey = makeStateKey("firestore:test/1");
23 | public readonly testDocValue;
24 |
25 | protected readonly className = signal("is-deferred");
26 |
27 | constructor() {
28 | this.firestore = getFirestore(inject(FirebaseApp));
29 | if (!(this.firestore as any)._settingsFrozen && environment.emulatorPorts?.firestore) {
30 | connectFirestoreEmulator(this.firestore, "localhost", environment.emulatorPorts.firestore);
31 | }
32 |
33 | this.testDocValue = docData(doc(this.firestore, 'test/1')).pipe(
34 | traceUntilFirst('firestore'),
35 | isPlatformServer(inject(PLATFORM_ID)) ?
36 | tap(it => this.transferState.set(this.transferStateKey, it)) :
37 | this.transferState.hasKey(this.transferStateKey) ?
38 | startWith(this.transferState.get(this.transferStateKey, undefined)) :
39 | tap()
40 | );
41 | }
42 |
43 | }
44 |
--------------------------------------------------------------------------------
/sample/src/app/functions/functions.component.ts:
--------------------------------------------------------------------------------
1 | import { JsonPipe } from '@angular/common';
2 | import { afterNextRender, Component, inject, signal } from '@angular/core';
3 | import { FirebaseApp } from '@angular/fire/app';
4 | import { connectFunctionsEmulator, getFunctions, httpsCallableData } from '@angular/fire/functions';
5 | import { environment } from '../../environments/environment';
6 |
7 | @Component({
8 | selector: 'app-functions',
9 | template: `
10 |
11 | Functions!
12 | {{ response() | json }}
13 | Call!
14 |
15 | `,
16 | imports: [JsonPipe]
17 | })
18 | export class FunctionsComponent {
19 |
20 | private readonly functions = getFunctions(inject(FirebaseApp));
21 |
22 | protected readonly response = signal(undefined);
23 | private readonly yadaFunction = httpsCallableData(this.functions, 'yada', { timeout: 3_000 });
24 |
25 | async request() {
26 | this.yadaFunction({}).subscribe({
27 | next: (next) => this.response.set(next),
28 | error: (error) => this.response.set(error),
29 | });
30 | }
31 |
32 | protected readonly className = signal("is-deferred");
33 |
34 | constructor() {
35 | if (environment.emulatorPorts?.functions) {
36 | connectFunctionsEmulator(this.functions, "localhost", environment.emulatorPorts.functions);
37 | }
38 |
39 | afterNextRender(() => {
40 | if (this.className) this.className.set("");
41 | });
42 | }
43 |
44 | }
45 |
--------------------------------------------------------------------------------
/sample/src/app/messaging/messaging.component.ts:
--------------------------------------------------------------------------------
1 | import { AsyncPipe, JsonPipe, SlicePipe } from '@angular/common';
2 | import { Component, inject, signal } from '@angular/core';
3 | import { Messaging } from '@angular/fire/messaging';
4 | import { EMPTY } from 'rxjs';
5 |
6 | @Component({
7 | selector: 'app-messaging',
8 | template: `
9 |
10 | Messaging!
11 | {{ token$ | async | slice:0:12 }} @if (token$ | async) { … }
12 | {{ message$ | async | json }}
13 | @if (showRequest()) {
14 | Request FCM token
15 | }
16 |
17 | `,
18 | imports: [AsyncPipe, SlicePipe, JsonPipe]
19 | })
20 | export class MessagingComponent {
21 |
22 | private readonly messaging = inject(Messaging, { optional: true });
23 | protected readonly token$ = EMPTY;
24 | protected readonly message$ = EMPTY;
25 |
26 | protected readonly showRequest = signal(false);
27 |
28 | async request() {
29 | await Notification.requestPermission();
30 | }
31 |
32 | }
33 |
--------------------------------------------------------------------------------
/sample/src/app/remote-config/remote-config.component.ts:
--------------------------------------------------------------------------------
1 | import { Component, inject, PLATFORM_ID } from '@angular/core';
2 | import { getAllChanges, getRemoteConfig } from '@angular/fire/remote-config';
3 | import { traceUntilFirst } from '@angular/fire/performance';
4 | import { EMPTY } from 'rxjs';
5 | import { AsyncPipe, isPlatformServer, JsonPipe } from '@angular/common';
6 | import { FirebaseApp } from '@angular/fire/app';
7 |
8 | @Component({
9 | selector: 'app-remote-config',
10 | template: `Remote Config! {{ config$ | async | json }}
`,
11 | imports: [AsyncPipe, JsonPipe],
12 | })
13 | export class RemoteConfigComponent {
14 |
15 | private readonly remoteConfig = isPlatformServer(inject(PLATFORM_ID)) ? undefined : getRemoteConfig(inject(FirebaseApp));
16 | protected readonly config$ = this.remoteConfig ?
17 | getAllChanges(this.remoteConfig).pipe(
18 | traceUntilFirst('remote-config'),
19 | ) :
20 | EMPTY;
21 |
22 | }
23 |
--------------------------------------------------------------------------------
/sample/src/app/storage/storage.component.ts:
--------------------------------------------------------------------------------
1 | import { Component, inject, makeStateKey, PLATFORM_ID, TransferState } from '@angular/core';
2 | import { from, startWith, tap } from 'rxjs';
3 | import { traceUntilFirst } from '@angular/fire/performance';
4 | import { connectStorageEmulator, getDownloadURL, getStorage, ref } from '@angular/fire/storage';
5 | import { AsyncPipe, isPlatformServer } from '@angular/common';
6 | import { FirebaseApp } from '@angular/fire/app';
7 | import { environment } from '../../environments/environment';
8 |
9 | const TRANSPARENT_PNG
10 | = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNkYAAAAAYAAjCB0C8AAAAASUVORK5CYII=';
11 |
12 | @Component({
13 | selector: 'app-storage',
14 | template: `
15 |
16 | Storage!
17 |
18 |
19 | `,
20 | imports: [AsyncPipe]
21 | })
22 | export class StorageComponent {
23 |
24 | private readonly storage = getStorage(inject(FirebaseApp));
25 |
26 | private readonly transferState = inject(TransferState);
27 | private readonly transferStateKey = makeStateKey("storage:google-g.png");
28 |
29 | private readonly icon = ref(this.storage, 'google-g.png');
30 |
31 | protected readonly downloadUrl$ = from(getDownloadURL(this.icon)).pipe(
32 | traceUntilFirst('storage'),
33 | isPlatformServer(inject(PLATFORM_ID)) ?
34 | tap(it => this.transferState.set(this.transferStateKey, it)) :
35 | startWith(this.transferState.get(this.transferStateKey, TRANSPARENT_PNG))
36 | );
37 |
38 | constructor() {
39 | if (environment.emulatorPorts?.storage) {
40 | connectStorageEmulator(this.storage, "localhost", environment.emulatorPorts.storage);
41 | }
42 | }
43 |
44 | }
45 |
--------------------------------------------------------------------------------
/sample/src/environments/environment.ts:
--------------------------------------------------------------------------------
1 | export const environment = {
2 | firebase: {
3 | apiKey: "AIzaSyBVSy3YpkVGiKXbbxeK0qBnu3-MNZ9UIjA",
4 | authDomain: "angularfire2-test.firebaseapp.com",
5 | databaseURL: "https://angularfire2-test.firebaseio.com",
6 | projectId: "angularfire2-test",
7 | storageBucket: "angularfire2-test.appspot.com",
8 | messagingSenderId: "920323787688",
9 | appId: "1:920323787688:web:2253a0e5eb5b9a8b",
10 | measurementId: "G-W20QDV5CZP"
11 | },
12 | emulatorPorts: {
13 | auth: 9099,
14 | functions: 5001,
15 | firestore: 8080,
16 | database: 9000,
17 | storage: 9199,
18 | },
19 | vapidKey: 'BObYLml9CWDGcaj2xQTv6MwjS-R5mRyTlCbfTpflWy3iGHEMTyIhhd0FN6VIFszPoVzwEL_gm7o9ISxpotwKHfE',
20 | recaptcha3SiteKey: '6LchwAoqAAAAAMfT_hY2nwI1WXJcBE20DGA_k-A3',
21 | };
22 |
--------------------------------------------------------------------------------
/sample/src/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Ng19Test
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/sample/src/main.server.ts:
--------------------------------------------------------------------------------
1 | import { bootstrapApplication } from '@angular/platform-browser';
2 | import { AppComponent } from './app/app.component';
3 | import { config } from './app/app.config.server';
4 |
5 | const bootstrap = () => bootstrapApplication(AppComponent, config);
6 |
7 | export default bootstrap;
8 |
--------------------------------------------------------------------------------
/sample/src/main.ts:
--------------------------------------------------------------------------------
1 | import { bootstrapApplication } from '@angular/platform-browser';
2 | import { config } from './app/app.config.client';
3 | import { AppComponent } from './app/app.component';
4 |
5 | bootstrapApplication(AppComponent, config)
6 | .catch((err) => console.error(err));
7 |
--------------------------------------------------------------------------------
/sample/src/server.ts:
--------------------------------------------------------------------------------
1 | import {
2 | AngularNodeAppEngine,
3 | createNodeRequestHandler,
4 | isMainModule,
5 | writeResponseToNodeResponse,
6 | } from '@angular/ssr/node';
7 | import express from 'express';
8 | import { dirname, resolve } from 'node:path';
9 | import { fileURLToPath } from 'node:url';
10 | import cookieParser from "cookie-parser";
11 |
12 | const serverDistFolder = dirname(fileURLToPath(import.meta.url));
13 | const browserDistFolder = resolve(serverDistFolder, '../browser');
14 |
15 | const app = express();
16 | const angularApp = new AngularNodeAppEngine();
17 |
18 | app.use(
19 | express.static(browserDistFolder, {
20 | maxAge: '1y',
21 | index: false,
22 | redirect: false,
23 | }),
24 | );
25 |
26 | app.use(cookieParser());
27 |
28 | app.use('/**', (req, res, next) => {
29 | angularApp
30 | .handle(req, { authIdToken: req.cookies?.__session })
31 | .then((response) =>
32 | response ? writeResponseToNodeResponse(response, res) : next(),
33 | )
34 | .catch(next);
35 | });
36 |
37 | if (isMainModule(import.meta.url)) {
38 | const port = process.env['PORT'] || 4000;
39 | app.listen(port, () => {
40 | console.log(`Node Express server listening on http://localhost:${port}`);
41 | });
42 | }
43 |
44 | export const reqHandler = createNodeRequestHandler(app);
45 |
--------------------------------------------------------------------------------
/sample/src/styles.css:
--------------------------------------------------------------------------------
1 | /* You can add global styles to this file, and also import other style files */
2 |
--------------------------------------------------------------------------------
/sample/storage.rules:
--------------------------------------------------------------------------------
1 | rules_version = '2';
2 | service firebase.storage {
3 | match /b/{bucket}/o {
4 | match /{allPaths=**} {
5 | allow read;
6 | allow write: if request.auth!=null;
7 | }
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/sample/tsconfig.app.json:
--------------------------------------------------------------------------------
1 | /* To learn more about Typescript configuration file: https://www.typescriptlang.org/docs/handbook/tsconfig-json.html. */
2 | /* To learn more about Angular compiler options: https://angular.dev/reference/configs/angular-compiler-options. */
3 | {
4 | "extends": "./tsconfig.json",
5 | "compilerOptions": {
6 | "outDir": "./out-tsc/app",
7 | "types": [
8 | "node"
9 | ]
10 | },
11 | "files": [
12 | "src/main.ts",
13 | "src/main.server.ts",
14 | "src/server.ts"
15 | ],
16 | "include": [
17 | "src/**/*.d.ts"
18 | ]
19 | }
20 |
--------------------------------------------------------------------------------
/sample/tsconfig.json:
--------------------------------------------------------------------------------
1 | /* To learn more about Typescript configuration file: https://www.typescriptlang.org/docs/handbook/tsconfig-json.html. */
2 | /* To learn more about Angular compiler options: https://angular.dev/reference/configs/angular-compiler-options. */
3 | {
4 | "compileOnSave": false,
5 | "compilerOptions": {
6 | "outDir": "./dist/out-tsc",
7 | "strict": true,
8 | "noImplicitOverride": true,
9 | "noPropertyAccessFromIndexSignature": true,
10 | "noImplicitReturns": true,
11 | "noFallthroughCasesInSwitch": true,
12 | "skipLibCheck": true,
13 | "isolatedModules": true,
14 | "esModuleInterop": true,
15 | "experimentalDecorators": true,
16 | "moduleResolution": "bundler",
17 | "importHelpers": true,
18 | "target": "ES2022",
19 | "module": "ES2022"
20 | },
21 | "angularCompilerOptions": {
22 | "enableI18nLegacyMessageIdFormat": false,
23 | "strictInjectionParameters": true,
24 | "strictInputAccessModifiers": true,
25 | "strictTemplates": true
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/sample/tsconfig.spec.json:
--------------------------------------------------------------------------------
1 | /* To learn more about Typescript configuration file: https://www.typescriptlang.org/docs/handbook/tsconfig-json.html. */
2 | /* To learn more about Angular compiler options: https://angular.dev/reference/configs/angular-compiler-options. */
3 | {
4 | "extends": "./tsconfig.json",
5 | "compilerOptions": {
6 | "outDir": "./out-tsc/spec",
7 | "types": [
8 | "jasmine"
9 | ]
10 | },
11 | "include": [
12 | "src/**/*.spec.ts",
13 | "src/**/*.d.ts"
14 | ]
15 | }
16 |
--------------------------------------------------------------------------------
/site/.firebaserc:
--------------------------------------------------------------------------------
1 | {
2 | "projects": {
3 | "default": "afdocsite"
4 | }
5 | }
6 |
--------------------------------------------------------------------------------
/site/.gitignore:
--------------------------------------------------------------------------------
1 | _site
2 | public
3 | _tmp
4 |
--------------------------------------------------------------------------------
/site/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "angularfire-guide",
3 | "version": "1.0.0",
4 | "description": "",
5 | "private": true,
6 | "scripts": {
7 | "start": "eleventy --serve & postcss ./src/styles/tailwind.css --o _tmp/style.css --watch",
8 | "quiet": "eleventy --quiet --serve & postcss ./src/styles/tailwind.css --o _tmp/style.css --watch",
9 | "just_a_comment_explaining_below": "The build scripts are read by scripts/build.js and executed in their number order (_0_, _1_, etc...), hence the weird naming system.",
10 | "build:_0_clean": "rm -rf _site",
11 | "build:_1_css": "NODE_ENV=production postcss ./src/styles/tailwind.css --o _site/style.css",
12 | "build:_2_eleventy": "ELEVENTY_PRODUCTION=true eleventy",
13 | "build": "node scripts/build.js"
14 | },
15 | "keywords": [],
16 | "author": "",
17 | "license": "ISC",
18 | "devDependencies": {
19 | "@11ty/eleventy": "^0.11.1",
20 | "@11ty/eleventy-navigation": "^0.1.6",
21 | "firebase-tools": "^9.3.0",
22 | "markdown-it": "^12.0.4",
23 | "markdown-it-attrs": "^3.0.3",
24 | "markdown-it-container": "^3.0.0",
25 | "markdown-it-prism": "^2.1.3",
26 | "markdown-it-replace-link": "^1.1.0",
27 | "nunjucks": "^3.2.2",
28 | "postcss-cli": "^8.3.1",
29 | "postcss-import": "^14.0.0",
30 | "shelljs": "^0.8.4",
31 | "tailwindcss": "^2.0.2"
32 | },
33 | "dependencies": {}
34 | }
35 |
--------------------------------------------------------------------------------
/site/postcss.config.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2021 Google LLC
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 | * https://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 | module.exports = {
18 | plugins: [
19 | require(`tailwindcss`)(`./src/styles/tailwind.config.js`),
20 | ],
21 | };
22 |
--------------------------------------------------------------------------------
/site/scripts/build.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2021 Google LLC
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 | * https://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 | const { exec, echo } = require('shelljs');
18 | const pkg = require('../package.json');
19 |
20 | function runExec(command) {
21 | if (exec(command).code !== 0) {
22 | echo(`${command} failed`);
23 | }
24 | }
25 |
26 | const buildScripts = Object.keys(pkg.scripts)
27 | .filter(k => k.startsWith('build:'));
28 |
29 | for(let script of buildScripts) {
30 | console.log(`Running npm run ${script}`);
31 | runExec(`npm run ${script}`);
32 | }
33 |
--------------------------------------------------------------------------------
/site/src/_includes/guide.njk:
--------------------------------------------------------------------------------
1 | {% extends "default.njk" %}
2 | {% import "next-prev.njk" as nextprev with context %}
3 |
4 | {% block content %}
5 |
6 | {{ title }}
7 |
8 | {{ content | safe }}
9 | {{ nextprev.contextgrid("guides") }}
10 |
11 | {% endblock %}
12 |
--------------------------------------------------------------------------------
/site/src/_includes/side-nav.njk:
--------------------------------------------------------------------------------
1 | {#
2 | Type of sectionEntry
3 | [{
4 | "key": "Mammals",
5 | "url": "/mammals/",
6 | "title": "Mammals",
7 | "children": [{
8 | "key": "Humans",
9 | "parentKey": "Mammals",
10 | "url": "/humans/",
11 | "title": "Humans"
12 | },
13 | {
14 | "key": "Dogs",
15 | "parentKey": "Mammals",
16 | "url": "/dogs/",
17 | "title": "Dogs"
18 | }]
19 | }]
20 | #}
21 |
22 | {% macro navsection(sectionEntry, page) %}
23 |
45 | {% endmacro %}
46 |
--------------------------------------------------------------------------------
/site/src/analytics/analytics.11tydata.json:
--------------------------------------------------------------------------------
1 | {
2 | "layout": "guide.njk",
3 | "tags": "guides"
4 | }
5 |
--------------------------------------------------------------------------------
/site/src/analytics/index.md:
--------------------------------------------------------------------------------
1 | ---
2 | eleventyNavigation:
3 | key: Analytics
4 | order: 5
5 | ---
6 |
7 |
--------------------------------------------------------------------------------
/site/src/assets/GoogleSans-Bold.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/angular/angularfire/c1c6af9779154caff6bc0d9b837f6c3e2d913456/site/src/assets/GoogleSans-Bold.woff2
--------------------------------------------------------------------------------
/site/src/assets/GoogleSans-Medium.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/angular/angularfire/c1c6af9779154caff6bc0d9b837f6c3e2d913456/site/src/assets/GoogleSans-Medium.woff2
--------------------------------------------------------------------------------
/site/src/assets/GoogleSans-Regular.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/angular/angularfire/c1c6af9779154caff6bc0d9b837f6c3e2d913456/site/src/assets/GoogleSans-Regular.woff2
--------------------------------------------------------------------------------
/site/src/assets/Roboto-900.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/angular/angularfire/c1c6af9779154caff6bc0d9b837f6c3e2d913456/site/src/assets/Roboto-900.woff2
--------------------------------------------------------------------------------
/site/src/assets/Roboto-Italic.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/angular/angularfire/c1c6af9779154caff6bc0d9b837f6c3e2d913456/site/src/assets/Roboto-Italic.woff2
--------------------------------------------------------------------------------
/site/src/assets/Roboto-Regular.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/angular/angularfire/c1c6af9779154caff6bc0d9b837f6c3e2d913456/site/src/assets/Roboto-Regular.woff2
--------------------------------------------------------------------------------
/site/src/assets/RobotoMono-Regular.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/angular/angularfire/c1c6af9779154caff6bc0d9b837f6c3e2d913456/site/src/assets/RobotoMono-Regular.woff2
--------------------------------------------------------------------------------
/site/src/assets/corner.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/site/src/auth/auth.11tydata.json:
--------------------------------------------------------------------------------
1 | {
2 | "layout": "guide.njk",
3 | "tags": "guides"
4 | }
5 |
--------------------------------------------------------------------------------
/site/src/auth/getting-started.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Getting started
3 | eleventyNavigation:
4 | key: Getting started
5 | parent: Auth
6 | ---
7 |
8 | ## Using AngularFireAuth
9 |
10 | `AngularFireAuth.user` provides you an `Observable` to monitor your application's authentication State.
11 |
12 | `AngularFireAuth` promise proxies an initialized
13 | `firebase.auth.Auth` instance, allowing you to log users in, out, etc. [See
14 | the Firebase docs for more information on what methods are available.](https://firebase.google.com/docs/reference/js/firebase.auth.Auth)
15 |
16 | **Example app:**
17 |
18 | ```ts
19 | import { Component } from '@angular/core';
20 | import { AngularFireAuth } from '@angular/fire/auth';
21 | import firebase from 'firebase/app';
22 |
23 | @Component({
24 | selector: 'app-root',
25 | template: `{%raw%}
26 |
27 |
Hello {{ user.displayName }}!
28 | Logout
29 |
30 |
31 | Please login.
32 | Login with Google
33 |
34 | {%endraw%}`,
35 | })
36 | export class AppComponent {
37 | constructor(public auth: AngularFireAuth) {
38 | }
39 | login() {
40 | this.auth.signInWithPopup(new firebase.auth.GoogleAuthProvider());
41 | }
42 | logout() {
43 | this.auth.signOut();
44 | }
45 | }
46 | ```
47 |
48 | ## UI Libraries
49 |
50 | - Material Design : [ngx-auth-firebaseui](https://github.com/AnthonyNahas/ngx-auth-firebaseui)
51 | - Bootstrap : [@firebaseui/ng-bootstrap](https://github.com/firebaseui/ng-bootstrap)
52 |
53 | ## Cordova
54 |
55 | Learn how to [setup Firebase Authentication with Cordova](https://firebase.google.com/docs/auth/web/cordova) in the Firebase Guides.
56 |
--------------------------------------------------------------------------------
/site/src/auth/index.md:
--------------------------------------------------------------------------------
1 | ---
2 | eleventyNavigation:
3 | key: Auth
4 | order: 3
5 | ---
6 |
--------------------------------------------------------------------------------
/site/src/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/angular/angularfire/c1c6af9779154caff6bc0d9b837f6c3e2d913456/site/src/favicon.ico
--------------------------------------------------------------------------------
/site/src/firestore/firestore.11tydata.json:
--------------------------------------------------------------------------------
1 | {
2 | "layout": "guide.njk",
3 | "tags": "guides"
4 | }
5 |
--------------------------------------------------------------------------------
/site/src/firestore/index.md:
--------------------------------------------------------------------------------
1 | ---
2 | eleventyNavigation:
3 | key: Firestore
4 | order: 2
5 | ---
--------------------------------------------------------------------------------
/site/src/functions/functions.11tydata.json:
--------------------------------------------------------------------------------
1 | {
2 | "layout": "guide.njk",
3 | "tags": "guides"
4 | }
5 |
--------------------------------------------------------------------------------
/site/src/functions/index.md:
--------------------------------------------------------------------------------
1 | ---
2 | eleventyNavigation:
3 | key: Functions
4 | order: 7
5 | ---
6 |
--------------------------------------------------------------------------------
/site/src/get-started/get-started.11tydata.json:
--------------------------------------------------------------------------------
1 | {
2 | "layout": "guide.njk",
3 | "tags": "guides"
4 | }
5 |
--------------------------------------------------------------------------------
/site/src/get-started/index.md:
--------------------------------------------------------------------------------
1 | ---
2 | eleventyNavigation:
3 | key: Get started
4 | order: 1
5 | ---
6 |
--------------------------------------------------------------------------------
/site/src/index.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: default.njk
3 | ---
4 |
5 | {% headingone %}AngularFire{% endheadingone %}
6 |
7 | {% subheading %}The official library for Angular and Firebase{% endsubheading %}
8 |
9 |
10 |
11 | {%- linkbutton "/get-started/quick-start" %}
12 | Get started
13 | {%- endlinkbutton %}
14 |
15 |
16 | {%- linkbutton "https://github.com/angular/fire", "secondary", true %}
17 | GitHub
18 | {%- endlinkbutton %}
19 |
20 |
21 |
22 | {% disclaimerprod %}
23 |
24 | ## What is AngularFire?
25 |
26 | AngularFire smooths over the rough edges an Angular developer might encounter when implementing the framework-agnostic Firebase JS SDK & aims to provide a more natural developer experience by conforming to Angular conventions.
27 |
28 | ### Dependency injection
29 | Provide and Inject Firebase services in your components
30 |
31 | ### Zone.js wrappers
32 | Stable zones allow proper functionality of service workers, forms, SSR, and pre-rendering
33 |
34 | ### Observable based
35 | Utilize RxJS rather than callbacks for realtime streams
36 |
37 | ### NgRx friendly API
38 | Integrate with NgRx using AngularFire's action based APIs.
39 |
40 | ### Lazy-loading
41 | AngularFire dynamically imports much of Firebase, reducing time to load your app
42 |
43 | ### Deploy schematics
44 | Get your Angular application deployed on Firebase Hosting with a single command
45 |
46 | ### Google Analytics
47 | Zero-effort Angular Router awareness in Google Analytics
48 |
49 | ### Router Guards
50 | Guard your Angular routes with built-in Firebase Authentication checks
51 |
--------------------------------------------------------------------------------
/site/src/ionic/index.md:
--------------------------------------------------------------------------------
1 | ---
2 | eleventyNavigation:
3 | key: Ionic
4 | order: 12
5 | ---
6 |
7 |
--------------------------------------------------------------------------------
/site/src/ionic/ionic.11tydata.json:
--------------------------------------------------------------------------------
1 | {
2 | "layout": "guide.njk",
3 | "tags": "guides"
4 | }
5 |
--------------------------------------------------------------------------------
/site/src/js/click-card.js:
--------------------------------------------------------------------------------
1 | customElements.define('eap-click-card', class extends HTMLElement {
2 | connectedCallback() {
3 | let down;
4 | let up;
5 | // Enhance to a pointer only if the JavaScript applies
6 | this.style.cursor = 'pointer';
7 | // Note: This only works for a single link or the first one.
8 | const firstOrOnlyLink = this.querySelector('a');
9 | this.onmousedown = () => down = +new Date();
10 | this.onmouseup = () => {
11 | up = +new Date();
12 | if ((up - down) < 200) {
13 | firstOrOnlyLink.click();
14 | }
15 | }
16 | }
17 | });
--------------------------------------------------------------------------------
/site/src/js/menu-button.js:
--------------------------------------------------------------------------------
1 | customElements.define('eap-menu-button', class extends HTMLElement {
2 | connectedCallback() {
3 | const menuId = this.getAttribute('data-menu-id');
4 | const menuEl = document.getElementById(menuId);
5 | const button = document.createElement('button');
6 | button.classList.add('fixed', 'w-16', 'h-16', 'text-white', 'rounded-full', 'shadow-lg', 'bottom-6', 'right-6', 'bg-grey-700', 'focus:ring-grey-600' , 'z-50', 'focus:ring-4', 'md:hidden', 'lg:hidden', 'xl:hidden');
7 | button.textContent = '🔥';
8 | this.appendChild(button);
9 | button.addEventListener('click', clickEvent => {
10 | menuEl.classList.toggle('slideIn');
11 | });
12 | }
13 | });
14 |
--------------------------------------------------------------------------------
/site/src/js/tab-switcher.js:
--------------------------------------------------------------------------------
1 | customElements.define('eap-tab-switcher', class extends HTMLElement {});
2 | customElements.define('eap-tab-list', class extends HTMLElement {
3 | connectedCallback() {
4 | this.buttonTabs = this.querySelectorAll('button');
5 | for(let button of this.buttonTabs) {
6 | button.addEventListener('click', clickEvent => {
7 | const activeButton = this.querySelector('button[aria-selected="true"]');
8 | const activePanelId = activeButton.dataset.panel;
9 | const panelToDisplayId = button.dataset.panel;
10 | const panelToDisplay = document.querySelector(`#${panelToDisplayId}`);
11 | const activePanel = document.querySelector(`#${activePanelId}`);
12 | if(activeButton.id !== button.id) {
13 | button.setAttribute('aria-selected', true);
14 | activeButton.setAttribute('aria-selected', false);
15 | panelToDisplay.classList.add('block');
16 | panelToDisplay.classList.remove('hidden');
17 | activePanel.classList.remove('block');
18 | activePanel.classList.add('hidden');
19 | }
20 | });
21 | }
22 | }
23 | });
24 | customElements.define('eap-tab-panel-list', class extends HTMLElement {});
25 | customElements.define('eap-tab-panel', class extends HTMLElement { });
--------------------------------------------------------------------------------
/site/src/messaging/index.md:
--------------------------------------------------------------------------------
1 | ---
2 | eleventyNavigation:
3 | key: Messaging
4 | order: 8
5 | ---
6 |
7 |
--------------------------------------------------------------------------------
/site/src/messaging/messaging.11tydata.json:
--------------------------------------------------------------------------------
1 | {
2 | "layout": "guide.njk",
3 | "tags": "guides"
4 | }
5 |
--------------------------------------------------------------------------------
/site/src/performance/index.md:
--------------------------------------------------------------------------------
1 | ---
2 | eleventyNavigation:
3 | key: Performance
4 | order: 10
5 | ---
6 |
--------------------------------------------------------------------------------
/site/src/performance/performance.11tydata.json:
--------------------------------------------------------------------------------
1 | {
2 | "layout": "guide.njk",
3 | "tags": "guides"
4 | }
5 |
--------------------------------------------------------------------------------
/site/src/remote-config/index.md:
--------------------------------------------------------------------------------
1 | ---
2 | eleventyNavigation:
3 | key: Remote Config
4 | order: 9
5 | ---
6 |
--------------------------------------------------------------------------------
/site/src/remote-config/remote-config.11tydata.json:
--------------------------------------------------------------------------------
1 | {
2 | "layout": "guide.njk",
3 | "tags": "guides"
4 | }
5 |
--------------------------------------------------------------------------------
/site/src/rtdb/index.md:
--------------------------------------------------------------------------------
1 | ---
2 | eleventyNavigation:
3 | key: RTDB
4 | order: 4
5 | ---
6 |
--------------------------------------------------------------------------------
/site/src/rtdb/rtdb.11tydata.json:
--------------------------------------------------------------------------------
1 | {
2 | "layout": "guide.njk",
3 | "tags": "guides"
4 | }
5 |
--------------------------------------------------------------------------------
/site/src/shortcodes/buttons/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2020 Google LLC
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 | * https://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 | const linkButton = {
18 | name: "linkbutton",
19 | type: "addPairedShortcode",
20 | create (content, href, type='primary', external=false) {
21 | const primaryClass = `link-button inline-block shadow-lg bg-blue text-white text-lg uppercase font-bold font-display tracking-wide rounded-lg px-8 py-3 text-center`;
22 | const secondaryClass = `link-button inline-block shadow-lg bg-blue-200 text-black text-lg uppercase font-bold font-display tracking-wide rounded-lg px-8 py-3 text-center`;
23 | const cssClass = type === 'primary' ? primaryClass : secondaryClass;
24 | const externalAttrs = external ? 'rel="noopener" target="blank"' : '';
25 | return `${content} `;
26 | }
27 | }
28 |
29 | module.exports = {
30 | shortcodes: [
31 | linkButton,
32 | ]
33 | };
34 |
--------------------------------------------------------------------------------
/site/src/shortcodes/disclaimerprod/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2020 Google LLC
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 | * https://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 | // Usage: {% disclaimerprod %}
18 | const disclaimerprod = {
19 | name: "disclaimerprod",
20 | type: "addShortcode",
21 | create() {
22 | return `
23 |
Beta Site!
24 |
This is a brand new guide site that is in beta. During this time period we'd love to hear your feedback on our GitHub Discussion board . Please let us know what you think of the usability, content, and any ideas for improvement. All contributors are welcome!
25 |
`;
26 | }
27 | }
28 |
29 | module.exports = {
30 | shortcodes: [
31 | disclaimerprod
32 | ]
33 | };
34 |
--------------------------------------------------------------------------------
/site/src/shortcodes/headings/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2020 Google LLC
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 | * https://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 | // Usage: {% headingone %} My title! {% endheadingone %}
18 | const headingOne = {
19 | name: "headingone",
20 | type: "addPairedShortcode",
21 | create (content) {
22 | return `${ content } `
23 | }
24 | };
25 |
26 | const subHeading = {
27 | name: "subheading",
28 | type: "addPairedShortcode",
29 | create (content) {
30 | return `${content}
`;
31 | }
32 | };
33 |
34 | module.exports = {
35 | shortcodes: [
36 | headingOne,
37 | subHeading,
38 | ]
39 | };
40 |
41 |
--------------------------------------------------------------------------------
/site/src/shortcodes/includecode/fetch.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2020 Google LLC
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 | * https://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 | const fetch = require("node-fetch");
18 |
19 | function convertToGitHubApiUrl(githubPath) {
20 | const urlPieces = githubPath.split('/');
21 | const [user, repo] = urlPieces.slice(0, 2);
22 | // TODO(davideast): Don't hardcode main branch
23 | const githubApiUrl = [user, repo, 'master', ...urlPieces.slice(2, urlPieces.length)].join('/');
24 | return `https://raw.githubusercontent.com/${githubApiUrl}`;
25 | }
26 |
27 | async function fetchCode(githubPath) {
28 | const githubApiUrl = convertToGitHubApiUrl(githubPath);
29 | const response = await fetch(githubApiUrl);
30 | return response.text();
31 | }
32 |
33 | module.exports = { fetchCode };
34 |
--------------------------------------------------------------------------------
/site/src/shortcodes/includecode/from-local.js:
--------------------------------------------------------------------------------
1 | const { readFile } = require('fs');
2 | const { resolve } = require('path');
3 | const { promisify } = require('util');
4 | const readFileAsync = promisify(readFile);
5 |
6 | function convertGitHubPathToLocal(githubPath) {
7 | return resolve(__dirname, '../../../repo_clones', githubPath);
8 | }
9 |
10 | async function fetchCode(githubPath = '') {
11 | let content = '';
12 | try {
13 | const localPath = convertGitHubPathToLocal(githubPath);
14 | content = await readFileAsync(localPath, 'utf-8');
15 | } catch(error) {
16 | console.error(error);
17 | content = 'File not found 😭';
18 | }
19 | return content;
20 | }
21 |
22 | module.exports = {
23 | fetchCode,
24 | };
25 |
--------------------------------------------------------------------------------
/site/src/shortcodes/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2020 Google LLC
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 | * https://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 | const { readdirSync, lstatSync } = require('fs');
18 | const { resolve } = require('path');
19 |
20 | /**
21 | * This sets up the shortcodes plugin to dynamically register
22 | * any shortcode in this directory, as long as it is is in
23 | * its own directory, exported in an index.js with an exports
24 | * of an array of shortcodes.
25 | *
26 | * Example:
27 | * / shortcodes
28 | * / includecode
29 | * + index.js
30 | * module.exports = { shortcodes: [...] }
31 | */
32 |
33 | const shortcodes = readdirSync(__dirname)
34 | .map(relativePath => resolve(__dirname, relativePath))
35 | .filter(absolutePath => lstatSync(absolutePath).isDirectory())
36 | .map(path => require(path).shortcodes)
37 | .flat();
38 |
39 | module.exports = {
40 | shortcodes
41 | };
42 |
--------------------------------------------------------------------------------
/site/src/shortcodes/version/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2020 Google LLC
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 | * https://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 | // Usage: {% version %}
18 | const version = {
19 | name: "version",
20 | type: "addShortcode",
21 | create () {
22 | return Date.now().toString();
23 | }
24 | };
25 |
26 | module.exports = {
27 | shortcodes: [
28 | version,
29 | ]
30 | };
31 |
--------------------------------------------------------------------------------
/site/src/storage/index.md:
--------------------------------------------------------------------------------
1 | ---
2 | eleventyNavigation:
3 | key: Storage
4 | order: 6
5 | ---
6 |
7 |
--------------------------------------------------------------------------------
/site/src/storage/storage.11tydata.json:
--------------------------------------------------------------------------------
1 | {
2 | "layout": "guide.njk",
3 | "tags": "guides"
4 | }
5 |
--------------------------------------------------------------------------------
/site/src/styles/tailwind.config.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2021 Google LLC
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 | * https://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 | module.exports = {
17 | purge: [
18 | "src/**/*.njk",
19 | "src/**/*.md",
20 | "src/**/*.js",
21 | ],
22 | darkMode: false, // or 'media' or 'class'
23 | theme: {
24 | fontFamily: {
25 | body: ['Roboto', 'Arial', 'sans-serif'],
26 | display: ['Google Sans', 'Arial', 'sans-serif'],
27 | mono: ['Roboto Mono', 'monospace'],
28 | },
29 | extend: {
30 | colors: {
31 | 'black': 'hsl(0 0% 0% / 87%)',
32 | 'blue-200': 'hsl(214 82% 50% / 7%)',
33 | 'blue': 'hsl(214 82% 50%)',
34 | 'navy': '#283142',
35 | 'grey': '#DADCE0',
36 | 'grey-200': '#ECEFF1',
37 | 'grey-300': 'hsl(0 0% 0% / 54%)',
38 | 'grey-600': 'hsl(213 5% 39% / 1)',
39 | 'grey-700': 'hsl(213 5% 19% / 1)',
40 | 'yellow': 'hsl(37 100% 94%)',
41 | 'orange': "#FF8F00",
42 | 'green': '#6CFF38',
43 | }
44 | },
45 | },
46 | variants: {
47 | extend: {},
48 | },
49 | plugins: [],
50 | }
--------------------------------------------------------------------------------
/site/src/universal/index.md:
--------------------------------------------------------------------------------
1 | ---
2 | eleventyNavigation:
3 | key: Universal
4 | order: 11
5 | ---
6 |
--------------------------------------------------------------------------------
/site/src/universal/universal.11tydata.json:
--------------------------------------------------------------------------------
1 | {
2 | "layout": "guide.njk",
3 | "tags": "guides"
4 | }
5 |
--------------------------------------------------------------------------------
/src/ai/ai.spec.ts:
--------------------------------------------------------------------------------
1 | import { TestBed } from '@angular/core/testing';
2 | import { AI, getAI, provideAI } from '@angular/fire/ai';
3 | import { FirebaseApp, getApp, initializeApp, provideFirebaseApp } from '@angular/fire/app';
4 | import { COMMON_CONFIG } from '../test-config';
5 | import { rando } from '../utils';
6 |
7 | describe('AI', () => {
8 | let app: FirebaseApp;
9 | let ai: AI;
10 | let providedAI: AI;
11 | let appName: string;
12 |
13 | describe('single injection', () => {
14 |
15 | beforeEach(() => {
16 | appName = rando();
17 | TestBed.configureTestingModule({
18 | providers: [
19 | provideFirebaseApp(() => initializeApp(COMMON_CONFIG, appName)),
20 | provideAI(() => {
21 | providedAI = getAI(getApp(appName));
22 | return providedAI;
23 | }),
24 | ],
25 | });
26 | app = TestBed.inject(FirebaseApp);
27 | ai = TestBed.inject(AI);
28 | });
29 |
30 | it('should be injectable', () => {
31 | expect(providedAI).toBeTruthy();
32 | expect(ai).toEqual(providedAI);
33 | expect(ai.app).toEqual(app);
34 | });
35 |
36 | });
37 |
38 | });
39 |
--------------------------------------------------------------------------------
/src/ai/ai.ts:
--------------------------------------------------------------------------------
1 | import { ɵgetAllInstancesOf } from '@angular/fire';
2 | import { AI as FirebaseAI } from 'firebase/ai';
3 | import { from, timer } from 'rxjs';
4 | import { concatMap, distinct } from 'rxjs/operators';
5 |
6 | // see notes in core/firebase.app.module.ts for why we're building the class like this
7 | // eslint-disable-next-line @typescript-eslint/no-empty-interface
8 | export interface AI extends FirebaseAI {}
9 |
10 | export class AI {
11 | constructor(ai: FirebaseAI) {
12 | return ai;
13 | }
14 | }
15 |
16 | export const AI_PROVIDER_NAME = 'AI';
17 |
18 | // eslint-disable-next-line @typescript-eslint/no-empty-interface
19 | export interface AIInstances extends Array {}
20 |
21 | export class AIInstances {
22 | constructor() {
23 | return ɵgetAllInstancesOf(AI_PROVIDER_NAME);
24 | }
25 | }
26 |
27 | export const AIInstance$ = timer(0, 300).pipe(
28 | concatMap(() => from(ɵgetAllInstancesOf(AI_PROVIDER_NAME))),
29 | distinct(),
30 | );
31 |
--------------------------------------------------------------------------------
/src/ai/firebase.ts:
--------------------------------------------------------------------------------
1 | // DO NOT MODIFY, this file is autogenerated by tools/build.ts
2 | export * from 'firebase/ai';
3 | import { ɵzoneWrap } from '@angular/fire';
4 | import {
5 | getAI as _getAI,
6 | getGenerativeModel as _getGenerativeModel,
7 | getImagenModel as _getImagenModel,
8 | getVertexAI as _getVertexAI
9 | } from 'firebase/ai';
10 |
11 | export const getAI = ɵzoneWrap(_getAI, true);
12 | export const getGenerativeModel = ɵzoneWrap(_getGenerativeModel, true);
13 | export const getImagenModel = ɵzoneWrap(_getImagenModel, true);
14 | export const getVertexAI = ɵzoneWrap(_getVertexAI, true);
15 |
--------------------------------------------------------------------------------
/src/ai/ng-package.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "../../node_modules/ng-packagr/ng-package.schema.json",
3 | "lib": {
4 | "entryFile": "public_api.ts"
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/src/ai/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "../../node_modules/ng-packagr/package.schema.json"
3 | }
4 |
--------------------------------------------------------------------------------
/src/ai/public_api.ts:
--------------------------------------------------------------------------------
1 | export { AI, AIInstances, AIInstance$ } from './ai';
2 | export { provideAI, AIModule } from './ai.module';
3 | export * from './firebase';
4 |
--------------------------------------------------------------------------------
/src/analytics/analytics.spec.ts:
--------------------------------------------------------------------------------
1 | import { TestBed } from '@angular/core/testing';
2 | import { Analytics, getAnalytics, provideAnalytics } from '@angular/fire/analytics';
3 | import { FirebaseApp, getApp, initializeApp, provideFirebaseApp } from '@angular/fire/app';
4 | import { COMMON_CONFIG_TOO } from '../test-config';
5 | import { rando } from '../utils';
6 |
7 | describe('Analytics', () => {
8 | let app: FirebaseApp;
9 | let analytics: Analytics;
10 | let providedAnalytics: Analytics;
11 | let appName: string;
12 |
13 | describe('single injection', () => {
14 |
15 | beforeEach(() => {
16 | appName = rando();
17 | TestBed.configureTestingModule({
18 | providers: [
19 | provideFirebaseApp(() => initializeApp(COMMON_CONFIG_TOO, appName)),
20 | provideAnalytics(() => {
21 | providedAnalytics = getAnalytics(getApp(appName));
22 | return providedAnalytics;
23 | }),
24 | ],
25 | });
26 | app = TestBed.inject(FirebaseApp);
27 | analytics = TestBed.inject(Analytics);
28 | });
29 |
30 | it('should be injectable', () => {
31 | expect(providedAnalytics).toBeTruthy();
32 | expect(analytics).toEqual(providedAnalytics);
33 | expect(analytics.app).toEqual(app);
34 | });
35 |
36 | });
37 |
38 | });
39 |
--------------------------------------------------------------------------------
/src/analytics/analytics.ts:
--------------------------------------------------------------------------------
1 | import { ɵgetAllInstancesOf } from '@angular/fire';
2 | import { Analytics as FirebaseAnalytics } from 'firebase/analytics';
3 | import { from, timer } from 'rxjs';
4 | import { concatMap, distinct } from 'rxjs/operators';
5 |
6 | // see notes in core/firebase.app.module.ts for why we're building the class like this
7 | // eslint-disable-next-line @typescript-eslint/no-empty-interface
8 | export interface Analytics extends FirebaseAnalytics {}
9 |
10 | export class Analytics {
11 | constructor(analytics: FirebaseAnalytics) {
12 | return analytics;
13 | }
14 | }
15 |
16 | export const ANALYTICS_PROVIDER_NAME = 'analytics';
17 |
18 | // eslint-disable-next-line @typescript-eslint/no-empty-interface
19 | export interface AnalyticsInstances extends Array {}
20 |
21 | export class AnalyticsInstances {
22 | constructor() {
23 | return ɵgetAllInstancesOf(ANALYTICS_PROVIDER_NAME);
24 | }
25 | }
26 |
27 | export const analyticInstance$ = timer(0, 300).pipe(
28 | concatMap(() => from(ɵgetAllInstancesOf(ANALYTICS_PROVIDER_NAME))),
29 | distinct(),
30 | );
31 |
--------------------------------------------------------------------------------
/src/analytics/firebase.ts:
--------------------------------------------------------------------------------
1 | // DO NOT MODIFY, this file is autogenerated by tools/build.ts
2 | export * from 'firebase/analytics';
3 | import { ɵzoneWrap } from '@angular/fire';
4 | import {
5 | getAnalytics as _getAnalytics,
6 | getGoogleAnalyticsClientId as _getGoogleAnalyticsClientId,
7 | initializeAnalytics as _initializeAnalytics,
8 | isSupported as _isSupported,
9 | logEvent as _logEvent,
10 | setAnalyticsCollectionEnabled as _setAnalyticsCollectionEnabled,
11 | setConsent as _setConsent,
12 | setCurrentScreen as _setCurrentScreen,
13 | setDefaultEventParameters as _setDefaultEventParameters,
14 | setUserId as _setUserId,
15 | setUserProperties as _setUserProperties,
16 | settings as _settings
17 | } from 'firebase/analytics';
18 |
19 | export const getAnalytics = ɵzoneWrap(_getAnalytics, true);
20 | export const getGoogleAnalyticsClientId = ɵzoneWrap(_getGoogleAnalyticsClientId, true);
21 | export const initializeAnalytics = ɵzoneWrap(_initializeAnalytics, true);
22 | export const isSupported = ɵzoneWrap(_isSupported, false);
23 | export const logEvent = ɵzoneWrap(_logEvent, false, 2);
24 | export const setAnalyticsCollectionEnabled = ɵzoneWrap(_setAnalyticsCollectionEnabled, true, 2);
25 | export const setConsent = ɵzoneWrap(_setConsent, true, 2);
26 | export const setCurrentScreen = ɵzoneWrap(_setCurrentScreen, true, 2);
27 | export const setDefaultEventParameters = ɵzoneWrap(_setDefaultEventParameters, true, 2);
28 | export const setUserId = ɵzoneWrap(_setUserId, true, 2);
29 | export const setUserProperties = ɵzoneWrap(_setUserProperties, true, 2);
30 | export const settings = ɵzoneWrap(_settings, true);
31 |
--------------------------------------------------------------------------------
/src/analytics/ng-package.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "../../node_modules/ng-packagr/ng-package.schema.json",
3 | "lib": {
4 | "entryFile": "public_api.ts"
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/src/analytics/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "../../node_modules/ng-packagr/package.schema.json"
3 | }
--------------------------------------------------------------------------------
/src/analytics/public_api.ts:
--------------------------------------------------------------------------------
1 | export { Analytics, AnalyticsInstances, analyticInstance$ } from './analytics';
2 | export { provideAnalytics, AnalyticsModule } from './analytics.module';
3 | export * from './firebase';
4 | export * from './screen-tracking.service';
5 | export * from './user-tracking.service';
6 |
--------------------------------------------------------------------------------
/src/analytics/user-tracking.service.ts:
--------------------------------------------------------------------------------
1 | import { Injectable, Injector, NgZone, OnDestroy } from '@angular/core';
2 | import { VERSION } from '@angular/fire';
3 | import { Auth, authState } from '@angular/fire/auth';
4 | import { registerVersion } from 'firebase/app';
5 | import { Subscription } from 'rxjs';
6 | import { Analytics } from './analytics';
7 | import { isSupported, setUserId } from './firebase';
8 |
9 | @Injectable()
10 | export class UserTrackingService implements OnDestroy {
11 |
12 | public readonly initialized: Promise;
13 | private disposables: Subscription[] = [];
14 |
15 | constructor(
16 | auth: Auth,
17 | zone: NgZone,
18 | injector: Injector,
19 | ) {
20 | registerVersion('angularfire', VERSION.full, 'user-tracking');
21 | let resolveInitialized: () => void;
22 | this.initialized = zone.runOutsideAngular(() => new Promise(resolve => { resolveInitialized = resolve; }));
23 | // The APP_INITIALIZER that is making isSupported() sync for the sake of convenient DI
24 | // may not be done when services are initialized. Guard the functionality by first ensuring
25 | // that the (global) promise has resolved, then get Analytics from the injector.
26 | isSupported().then(() => {
27 | const analytics = injector.get(Analytics);
28 | if (analytics) {
29 | this.disposables = [
30 | // TODO add credential tracking back in
31 | authState(auth).subscribe(user => {
32 | setUserId(analytics, user?.uid);
33 | resolveInitialized();
34 | }),
35 | ];
36 | } else {
37 | resolveInitialized();
38 | }
39 | });
40 | }
41 |
42 | ngOnDestroy() {
43 | this.disposables.forEach(it => it.unsubscribe());
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/src/app-check/app-check.spec.ts:
--------------------------------------------------------------------------------
1 | import { TestBed } from '@angular/core/testing';
2 | import { FirebaseApp, getApp, initializeApp, provideFirebaseApp } from '@angular/fire/app';
3 | import { Auth, connectAuthEmulator, getAuth, provideAuth } from '@angular/fire/auth';
4 | import { COMMON_CONFIG } from '../test-config';
5 | import { rando } from '../utils';
6 |
7 | describe('Auth', () => {
8 | let app: FirebaseApp;
9 | let auth: Auth;
10 | let providedAuth: Auth;
11 | let appName: string;
12 |
13 | describe('single injection', () => {
14 |
15 | beforeEach(() => {
16 | appName = rando();
17 | TestBed.configureTestingModule({
18 | providers: [
19 | provideFirebaseApp(() => initializeApp(COMMON_CONFIG, appName)),
20 | provideAuth(() => {
21 | providedAuth = getAuth(getApp(appName));
22 | connectAuthEmulator(providedAuth, 'http://localhost:9098');
23 | return providedAuth;
24 | }),
25 | ],
26 | });
27 | app = TestBed.inject(FirebaseApp);
28 | auth = TestBed.inject(Auth);
29 | });
30 |
31 | it('should be injectable', () => {
32 | expect(auth).toBeTruthy();
33 | expect(auth).toEqual(providedAuth);
34 | expect(auth.app).toEqual(app);
35 | });
36 |
37 | });
38 |
39 | });
40 |
--------------------------------------------------------------------------------
/src/app-check/app-check.ts:
--------------------------------------------------------------------------------
1 | import { ɵgetAllInstancesOf } from '@angular/fire';
2 | import { AppCheck as FirebaseAppCheck } from 'firebase/app-check';
3 | import { from, timer } from 'rxjs';
4 | import { concatMap, distinct } from 'rxjs/operators';
5 |
6 | export const APP_CHECK_PROVIDER_NAME = 'app-check';
7 |
8 | // see notes in core/firebase.app.module.ts for why we're building the class like this
9 | // eslint-disable-next-line @typescript-eslint/no-empty-interface
10 | export interface AppCheck extends FirebaseAppCheck {}
11 |
12 | export class AppCheck {
13 | constructor(appCheck: FirebaseAppCheck) {
14 | return appCheck;
15 | }
16 | }
17 |
18 | // eslint-disable-next-line @typescript-eslint/no-empty-interface
19 | export interface AppCheckInstances extends Array {}
20 |
21 | export class AppCheckInstances {
22 | constructor() {
23 | return ɵgetAllInstancesOf(APP_CHECK_PROVIDER_NAME);
24 | }
25 | }
26 |
27 | export const appCheckInstance$ = timer(0, 300).pipe(
28 | concatMap(() => from(ɵgetAllInstancesOf(APP_CHECK_PROVIDER_NAME))),
29 | distinct(),
30 | );
31 |
--------------------------------------------------------------------------------
/src/app-check/firebase.ts:
--------------------------------------------------------------------------------
1 | // DO NOT MODIFY, this file is autogenerated by tools/build.ts
2 | export * from 'firebase/app-check';
3 | import { ɵzoneWrap } from '@angular/fire';
4 | import {
5 | getLimitedUseToken as _getLimitedUseToken,
6 | getToken as _getToken,
7 | initializeAppCheck as _initializeAppCheck,
8 | onTokenChanged as _onTokenChanged,
9 | setTokenAutoRefreshEnabled as _setTokenAutoRefreshEnabled
10 | } from 'firebase/app-check';
11 |
12 | export const getLimitedUseToken = ɵzoneWrap(_getLimitedUseToken, true, 2);
13 | export const getToken = ɵzoneWrap(_getToken, true);
14 | export const initializeAppCheck = ɵzoneWrap(_initializeAppCheck, true);
15 | export const onTokenChanged = ɵzoneWrap(_onTokenChanged, true);
16 | export const setTokenAutoRefreshEnabled = ɵzoneWrap(_setTokenAutoRefreshEnabled, true);
17 |
--------------------------------------------------------------------------------
/src/app-check/ng-package.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "../../node_modules/ng-packagr/ng-package.schema.json",
3 | "lib": {
4 | "entryFile": "public_api.ts"
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/src/app-check/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "../../node_modules/ng-packagr/package.schema.json"
3 | }
--------------------------------------------------------------------------------
/src/app-check/public_api.ts:
--------------------------------------------------------------------------------
1 | export { AppCheck, appCheckInstance$, AppCheckInstances } from './app-check';
2 | export { provideAppCheck, AppCheckModule } from './app-check.module';
3 | export * from './firebase';
4 |
--------------------------------------------------------------------------------
/src/app/app.spec.ts:
--------------------------------------------------------------------------------
1 | import { TestBed } from '@angular/core/testing';
2 | import { FirebaseApp, initializeApp, provideFirebaseApp } from '@angular/fire/app';
3 | import { COMMON_CONFIG } from '../test-config';
4 | import { rando } from '../utils';
5 |
6 | describe('FirebaseApp', () => {
7 | let app: FirebaseApp;
8 | let providedApp: FirebaseApp;
9 | let appName: string;
10 |
11 | describe('single injection', () => {
12 |
13 | beforeEach(() => {
14 | appName = rando();
15 | TestBed.configureTestingModule({
16 | providers: [
17 | provideFirebaseApp(() => {
18 | providedApp = initializeApp(COMMON_CONFIG, appName);
19 | return providedApp;
20 | })
21 | ],
22 | });
23 | app = TestBed.inject(FirebaseApp);
24 | });
25 |
26 | it('should be injectable', () => {
27 | expect(app).toBeTruthy();
28 | expect(app).toEqual(providedApp);
29 | });
30 |
31 | });
32 |
33 | });
34 |
--------------------------------------------------------------------------------
/src/app/app.ts:
--------------------------------------------------------------------------------
1 | import { FirebaseApp as IFirebaseApp, getApps } from 'firebase/app';
2 | import { from, timer } from 'rxjs';
3 | import { concatMap, distinct } from 'rxjs/operators';
4 |
5 | // Need to turn the FirebaseApp interface exported by firebase/app into a class
6 | // as types don't work in Angular DI. We want developers to be able to inject FirebaseApp like so
7 | // constructor(app: FirebaseApp)
8 | // the cleanest way to achieve this that I found is to export a new interface and class
9 | // the interface just extends the interface you want to turn into the class. This informs tyepscript
10 | // that the class has all the same methods/properties as the interface you want to extend without
11 | // breaking if Firebase adds/removes APIs in future releases. This was a big problem for @angular/fire
12 | // back when we constructed our own class. Then in the "new class" we just return the FirebaseApp in the
13 | // constructor, this also has the added benefit of Firebase methods taking our DI class without
14 | // casting. E.g,
15 | // constructor(private app: FirebaseApp) { }
16 | // ngOnDestroy() { deleteApp(this.app); }
17 | //
18 | // eslint-disable-next-line @typescript-eslint/no-empty-interface
19 | export interface FirebaseApp extends IFirebaseApp {}
20 |
21 | export class FirebaseApp {
22 | constructor(app: IFirebaseApp) {
23 | return app;
24 | }
25 | }
26 |
27 | // eslint-disable-next-line @typescript-eslint/no-empty-interface
28 | export interface FirebaseApps extends Array {}
29 |
30 | export class FirebaseApps {
31 | constructor() {
32 | return getApps();
33 | }
34 | }
35 |
36 | export const firebaseApp$ = timer(0, 300).pipe(
37 | concatMap(() => from(getApps())),
38 | distinct(),
39 | );
40 |
--------------------------------------------------------------------------------
/src/app/firebase.ts:
--------------------------------------------------------------------------------
1 | // DO NOT MODIFY, this file is autogenerated by tools/build.ts
2 | export * from 'firebase/app';
3 | import { ɵzoneWrap } from '@angular/fire';
4 | import {
5 | deleteApp as _deleteApp,
6 | getApp as _getApp,
7 | getApps as _getApps,
8 | initializeApp as _initializeApp,
9 | initializeServerApp as _initializeServerApp,
10 | onLog as _onLog,
11 | registerVersion as _registerVersion,
12 | setLogLevel as _setLogLevel
13 | } from 'firebase/app';
14 |
15 | export const deleteApp = ɵzoneWrap(_deleteApp, true);
16 | export const getApp = ɵzoneWrap(_getApp, true);
17 | export const getApps = ɵzoneWrap(_getApps, true);
18 | export const initializeApp = ɵzoneWrap(_initializeApp, true);
19 | export const initializeServerApp = ɵzoneWrap(_initializeServerApp, true);
20 | export const onLog = ɵzoneWrap(_onLog, true);
21 | export const registerVersion = ɵzoneWrap(_registerVersion, true);
22 | export const setLogLevel = ɵzoneWrap(_setLogLevel, true);
23 |
--------------------------------------------------------------------------------
/src/app/ng-package.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "../../node_modules/ng-packagr/ng-package.schema.json",
3 | "lib": {
4 | "entryFile": "public_api.ts"
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/src/app/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "../../node_modules/ng-packagr/package.schema.json"
3 | }
--------------------------------------------------------------------------------
/src/app/public_api.ts:
--------------------------------------------------------------------------------
1 | export { FirebaseApp, FirebaseApps, firebaseApp$ } from './app';
2 | export { provideFirebaseApp, FirebaseAppModule } from './app.module';
3 | export * from './firebase';
4 |
--------------------------------------------------------------------------------
/src/auth-guard/auth-guard.module.ts:
--------------------------------------------------------------------------------
1 | import { NgModule } from '@angular/core';
2 | import { VERSION } from '@angular/fire';
3 | import { registerVersion } from 'firebase/app';
4 | import { AuthGuard } from './auth-guard';
5 |
6 | @NgModule({
7 | providers: [ AuthGuard ]
8 | })
9 | export class AuthGuardModule {
10 | constructor() {
11 | registerVersion('angularfire', VERSION.full, 'auth-guard');
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/src/auth-guard/auth-guard.spec.ts:
--------------------------------------------------------------------------------
1 | import { APP_BASE_HREF } from '@angular/common';
2 | import { TestBed } from '@angular/core/testing';
3 | import { getApp, initializeApp, provideFirebaseApp } from '@angular/fire/app';
4 | import { connectAuthEmulator, getAuth, provideAuth } from '@angular/fire/auth';
5 | import { AuthGuard, AuthGuardModule } from '@angular/fire/auth-guard';
6 | import { Router, RouterModule } from '@angular/router';
7 | import { COMMON_CONFIG } from '../test-config';
8 | import { rando } from '../utils';
9 |
10 | class TestComponent { }
11 |
12 | describe('AuthGuard', () => {
13 | let router: Router;
14 | let appName: string;
15 |
16 | beforeEach(() => {
17 | appName = rando();
18 | TestBed.configureTestingModule({
19 | imports: [
20 | AuthGuardModule,
21 | RouterModule.forRoot([
22 | { path: 'a', component: TestComponent, canActivate: [AuthGuard] }
23 | ])
24 | ],
25 | providers: [
26 | provideFirebaseApp(() => initializeApp(COMMON_CONFIG, appName)),
27 | provideAuth(() => {
28 | const auth = getAuth(getApp(appName));
29 | connectAuthEmulator(auth, 'http://localhost:9098');
30 | return auth;
31 | }),
32 | { provide: APP_BASE_HREF, useValue: 'http://localhost:4200/' }
33 | ]
34 | });
35 |
36 | router = TestBed.inject(Router);
37 | });
38 |
39 | it('should be injectable', () => {
40 | expect(AuthGuard).toBeTruthy();
41 | });
42 |
43 | it('router should be valid', () => {
44 | expect(router).toBeTruthy();
45 | });
46 |
47 | });
48 |
--------------------------------------------------------------------------------
/src/auth-guard/ng-package.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "../../node_modules/ng-packagr/ng-package.schema.json",
3 | "lib": {
4 | "entryFile": "public_api.ts"
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/src/auth-guard/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "../../node_modules/ng-packagr/package.schema.json"
3 | }
4 |
--------------------------------------------------------------------------------
/src/auth-guard/public_api.ts:
--------------------------------------------------------------------------------
1 | export * from './auth-guard';
2 | export * from './auth-guard.module';
3 |
--------------------------------------------------------------------------------
/src/auth/auth.spec.ts:
--------------------------------------------------------------------------------
1 | import { TestBed } from '@angular/core/testing';
2 | import { FirebaseApp, getApp, initializeApp, provideFirebaseApp } from '@angular/fire/app';
3 | import { Auth, connectAuthEmulator, getAuth, provideAuth } from '@angular/fire/auth';
4 | import { COMMON_CONFIG, authEmulatorPort } from '../test-config';
5 | import { rando } from '../utils';
6 |
7 | describe('Auth', () => {
8 | let app: FirebaseApp;
9 | let auth: Auth;
10 | let providedAuth: Auth;
11 | let appName: string;
12 |
13 | describe('single injection', () => {
14 |
15 | beforeEach(() => {
16 | appName = rando();
17 | TestBed.configureTestingModule({
18 | providers: [
19 | provideFirebaseApp(() => initializeApp(COMMON_CONFIG, appName)),
20 | provideAuth(() => {
21 | providedAuth = getAuth(getApp(appName));
22 | connectAuthEmulator(providedAuth, `http://localhost:${authEmulatorPort}`, { disableWarnings: true });
23 | return providedAuth;
24 | }),
25 | ],
26 | });
27 | app = TestBed.inject(FirebaseApp);
28 | auth = TestBed.inject(Auth);
29 | });
30 |
31 | it('should be injectable', () => {
32 | expect(providedAuth).toBeTruthy();
33 | expect(auth).toEqual(providedAuth);
34 | expect(auth.app).toEqual(app);
35 | });
36 |
37 | });
38 |
39 | });
40 |
--------------------------------------------------------------------------------
/src/auth/auth.ts:
--------------------------------------------------------------------------------
1 | import { ɵgetAllInstancesOf } from '@angular/fire';
2 | import { Auth as FirebaseAuth } from 'firebase/auth';
3 | import { from, timer } from 'rxjs';
4 | import { concatMap, distinct } from 'rxjs/operators';
5 |
6 | export const AUTH_PROVIDER_NAME = 'auth';
7 |
8 | // see notes in core/firebase.app.module.ts for why we're building the class like this
9 | // eslint-disable-next-line @typescript-eslint/no-empty-interface
10 | export interface Auth extends FirebaseAuth {}
11 |
12 | export class Auth {
13 | constructor(auth: FirebaseAuth) {
14 | return auth;
15 | }
16 | }
17 |
18 | // eslint-disable-next-line @typescript-eslint/no-empty-interface
19 | export interface AuthInstances extends Array {}
20 |
21 | export class AuthInstances {
22 | constructor() {
23 | return ɵgetAllInstancesOf(AUTH_PROVIDER_NAME);
24 | }
25 | }
26 |
27 | export const authInstance$ = timer(0, 300).pipe(
28 | concatMap(() => from(ɵgetAllInstancesOf(AUTH_PROVIDER_NAME))),
29 | distinct(),
30 | );
31 |
--------------------------------------------------------------------------------
/src/auth/ng-package.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "../../node_modules/ng-packagr/ng-package.schema.json",
3 | "lib": {
4 | "entryFile": "public_api.ts"
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/src/auth/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "../../node_modules/ng-packagr/package.schema.json"
3 | }
--------------------------------------------------------------------------------
/src/auth/public_api.ts:
--------------------------------------------------------------------------------
1 | export { Auth, AuthInstances, authInstance$ } from './auth';
2 | export { provideAuth, AuthModule } from './auth.module';
3 | export * from './rxfire';
4 | export * from './firebase';
5 |
--------------------------------------------------------------------------------
/src/auth/rxfire.ts:
--------------------------------------------------------------------------------
1 | // DO NOT MODIFY, this file is autogenerated by tools/build.ts
2 | import { ɵzoneWrap } from '@angular/fire';
3 | import {
4 | authState as _authState,
5 | idToken as _idToken,
6 | user as _user
7 | } from 'rxfire/auth';
8 |
9 | export const authState = ɵzoneWrap(_authState, true);
10 | export const idToken = ɵzoneWrap(_idToken, true);
11 | export const user = ɵzoneWrap(_user, true);
12 |
--------------------------------------------------------------------------------
/src/compat/analytics/analytics.module.ts:
--------------------------------------------------------------------------------
1 | import { NgModule, Optional } from '@angular/core';
2 | import { VERSION } from '@angular/fire';
3 | import firebase from 'firebase/compat/app';
4 | import { AngularFireAnalytics } from './analytics';
5 | import { ScreenTrackingService } from './screen-tracking.service';
6 | import { UserTrackingService } from './user-tracking.service';
7 |
8 | @NgModule({
9 | providers: [ AngularFireAnalytics ]
10 | })
11 | export class AngularFireAnalyticsModule {
12 | constructor(
13 | analytics: AngularFireAnalytics,
14 | // eslint-disable-next-line @typescript-eslint/no-unused-vars
15 | @Optional() screenTracking: ScreenTrackingService,
16 | // eslint-disable-next-line @typescript-eslint/no-unused-vars
17 | @Optional() userTracking: UserTrackingService,
18 | ) {
19 | firebase.registerVersion('angularfire', VERSION.full, 'analytics-compat');
20 | // calling anything on analytics will eagerly load the SDK
21 | analytics.app.then(() => undefined);
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/src/compat/analytics/analytics.spec.ts:
--------------------------------------------------------------------------------
1 | import { TestBed } from '@angular/core/testing';
2 | import { AngularFireModule } from '@angular/fire/compat';
3 | import { AngularFireAnalytics, AngularFireAnalyticsModule } from '@angular/fire/compat/analytics';
4 | import { COMMON_CONFIG } from '../../test-config';
5 | import { rando } from '../../utils';
6 |
7 |
8 | describe('AngularFireAnalytics', () => {
9 | let analytics: AngularFireAnalytics;
10 |
11 | beforeEach(() => {
12 | TestBed.configureTestingModule({
13 | imports: [
14 | AngularFireModule.initializeApp(COMMON_CONFIG, rando()),
15 | AngularFireAnalyticsModule
16 | ]
17 | });
18 |
19 | analytics = TestBed.inject(AngularFireAnalytics);
20 | });
21 |
22 | it('should be exist', () => {
23 | expect(analytics instanceof AngularFireAnalytics).toBe(true);
24 | });
25 |
26 | it('should have the Firebase Functions instance', () => {
27 | expect(analytics.app).toBeDefined();
28 | });
29 |
30 | });
31 |
--------------------------------------------------------------------------------
/src/compat/analytics/base.ts:
--------------------------------------------------------------------------------
1 | // DO NOT MODIFY, this file is autogenerated by tools/build.ts
2 | // Export a null object with the same keys as firebase/compat/analytics, so Proxy can work with proxy-polyfill in Internet Explorer
3 | export const proxyPolyfillCompat = {
4 | app: null,
5 | logEvent: null,
6 | setCurrentScreen: null,
7 | setUserId: null,
8 | setUserProperties: null,
9 | setAnalyticsCollectionEnabled: null,
10 | };
11 |
--------------------------------------------------------------------------------
/src/compat/analytics/index.ts:
--------------------------------------------------------------------------------
1 | export * from './public_api';
2 |
--------------------------------------------------------------------------------
/src/compat/analytics/ng-package.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "../../../node_modules/ng-packagr/ng-package.schema.json",
3 | "lib": {
4 | "entryFile": "public_api.ts"
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/src/compat/analytics/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "../../../node_modules/ng-packagr/package.schema.json"
3 | }
4 |
--------------------------------------------------------------------------------
/src/compat/analytics/public_api.ts:
--------------------------------------------------------------------------------
1 | export * from './analytics';
2 | export * from './analytics.module';
3 | export * from './screen-tracking.service';
4 | export * from './user-tracking.service';
5 |
--------------------------------------------------------------------------------
/src/compat/analytics/screen-tracking.service.ts:
--------------------------------------------------------------------------------
1 | import { ComponentFactoryResolver, Injectable, NgZone, OnDestroy, Optional } from '@angular/core';
2 | import { VERSION } from '@angular/fire';
3 | import { ɵscreenViewEvent } from '@angular/fire/analytics';
4 | import { Title } from '@angular/platform-browser';
5 | import { Router } from '@angular/router';
6 | import firebase from 'firebase/compat/app';
7 | import { Subscription } from 'rxjs';
8 | import { switchMap } from 'rxjs/operators';
9 | import { AngularFireAnalytics } from './analytics';
10 | import { UserTrackingService } from './user-tracking.service';
11 |
12 | const SCREEN_VIEW_EVENT = 'screen_view';
13 |
14 | @Injectable()
15 | export class ScreenTrackingService implements OnDestroy {
16 |
17 | private disposable: Subscription | undefined;
18 |
19 | constructor(
20 | analytics: AngularFireAnalytics,
21 | @Optional() router: Router,
22 | @Optional() title: Title,
23 | componentFactoryResolver: ComponentFactoryResolver,
24 | zone: NgZone,
25 | @Optional() userTrackingService: UserTrackingService,
26 | ) {
27 | firebase.registerVersion('angularfire', VERSION.full, 'compat-screen-tracking');
28 | if (!router || !analytics) { return this; }
29 | zone.runOutsideAngular(() => {
30 | this.disposable = ɵscreenViewEvent(router, title, componentFactoryResolver).pipe(
31 | switchMap(async params => {
32 | if (userTrackingService) {
33 | await userTrackingService.initialized;
34 | }
35 | return await analytics.logEvent(SCREEN_VIEW_EVENT, params);
36 | })
37 | ).subscribe();
38 | });
39 | }
40 |
41 | ngOnDestroy() {
42 | if (this.disposable) {
43 | this.disposable.unsubscribe();
44 | }
45 | }
46 |
47 | }
48 |
--------------------------------------------------------------------------------
/src/compat/auth-guard/auth-guard.module.ts:
--------------------------------------------------------------------------------
1 | import { NgModule } from '@angular/core';
2 | import { VERSION } from '@angular/fire';
3 | import firebase from 'firebase/compat/app';
4 | import { AngularFireAuthGuard } from './auth-guard';
5 |
6 | @NgModule({
7 | providers: [ AngularFireAuthGuard ]
8 | })
9 | export class AngularFireAuthGuardModule {
10 | constructor() {
11 | firebase.registerVersion('angularfire', VERSION.full, 'auth-guard-compat');
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/src/compat/auth-guard/auth-guard.spec.ts:
--------------------------------------------------------------------------------
1 | import { APP_BASE_HREF } from '@angular/common';
2 | import { TestBed } from '@angular/core/testing';
3 | import { AngularFireModule } from '@angular/fire/compat';
4 | import { AngularFireAuthGuard, AngularFireAuthGuardModule } from '@angular/fire/compat/auth-guard';
5 | import { Router, RouterModule } from '@angular/router';
6 | import { COMMON_CONFIG } from '../../../src/test-config';
7 | import { rando } from '../../../src/utils';
8 |
9 | class TestComponent { }
10 |
11 | describe('AngularFireAuthGuard', () => {
12 | let router: Router;
13 |
14 | beforeEach(() => {
15 | TestBed.configureTestingModule({
16 | imports: [
17 | AngularFireModule.initializeApp(COMMON_CONFIG, rando()),
18 | AngularFireAuthGuardModule,
19 | RouterModule.forRoot([
20 | { path: 'a', component: TestComponent, canActivate: [AngularFireAuthGuard] }
21 | ])
22 | ],
23 | providers: [
24 | { provide: APP_BASE_HREF, useValue: 'http://localhost:4200/' }
25 | ]
26 | });
27 |
28 | router = TestBed.inject(Router);
29 | });
30 |
31 | it('should be injectable', () => {
32 | expect(router).toBeTruthy();
33 | });
34 | });
35 |
--------------------------------------------------------------------------------
/src/compat/auth-guard/ng-package.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "../../../node_modules/ng-packagr/ng-package.schema.json",
3 | "lib": {
4 | "entryFile": "public_api.ts"
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/src/compat/auth-guard/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "../../../node_modules/ng-packagr/package.schema.json"
3 | }
4 |
--------------------------------------------------------------------------------
/src/compat/auth-guard/public_api.ts:
--------------------------------------------------------------------------------
1 | export * from './auth-guard';
2 | export * from './auth-guard.module';
3 |
--------------------------------------------------------------------------------
/src/compat/auth/auth.module.ts:
--------------------------------------------------------------------------------
1 | import { NgModule } from '@angular/core';
2 | import { VERSION } from '@angular/fire';
3 | import firebase from 'firebase/compat/app';
4 | import { AngularFireAuth } from './auth';
5 |
6 | @NgModule({
7 | providers: [ AngularFireAuth ]
8 | })
9 | export class AngularFireAuthModule {
10 | constructor() {
11 | firebase.registerVersion('angularfire', VERSION.full, 'auth-compat');
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/src/compat/auth/base.ts:
--------------------------------------------------------------------------------
1 | // DO NOT MODIFY, this file is autogenerated by tools/build.ts
2 | // Export a null object with the same keys as firebase/compat/auth, so Proxy can work with proxy-polyfill in Internet Explorer
3 | export const proxyPolyfillCompat = {
4 | name: null,
5 | config: null,
6 | emulatorConfig: null,
7 | app: null,
8 | applyActionCode: null,
9 | checkActionCode: null,
10 | confirmPasswordReset: null,
11 | createUserWithEmailAndPassword: null,
12 | currentUser: null,
13 | fetchSignInMethodsForEmail: null,
14 | isSignInWithEmailLink: null,
15 | getRedirectResult: null,
16 | languageCode: null,
17 | settings: null,
18 | onAuthStateChanged: null,
19 | onIdTokenChanged: null,
20 | sendSignInLinkToEmail: null,
21 | sendPasswordResetEmail: null,
22 | setPersistence: null,
23 | signInAndRetrieveDataWithCredential: null,
24 | signInAnonymously: null,
25 | signInWithCredential: null,
26 | signInWithCustomToken: null,
27 | signInWithEmailAndPassword: null,
28 | signInWithPhoneNumber: null,
29 | signInWithEmailLink: null,
30 | signInWithPopup: null,
31 | signInWithRedirect: null,
32 | signOut: null,
33 | tenantId: null,
34 | updateCurrentUser: null,
35 | useDeviceLanguage: null,
36 | useEmulator: null,
37 | verifyPasswordResetCode: null,
38 | };
39 |
--------------------------------------------------------------------------------
/src/compat/auth/ng-package.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "../../../node_modules/ng-packagr/ng-package.schema.json",
3 | "lib": {
4 | "entryFile": "public_api.ts"
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/src/compat/auth/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "../../../node_modules/ng-packagr/package.schema.json"
3 | }
4 |
--------------------------------------------------------------------------------
/src/compat/auth/public_api.ts:
--------------------------------------------------------------------------------
1 |
2 | import 'firebase/compat/auth'; // removed in build process when not UMD
3 |
4 | export * from './auth';
5 | export * from './auth.module';
6 |
--------------------------------------------------------------------------------
/src/compat/cache.ts:
--------------------------------------------------------------------------------
1 | import { isDevMode } from '@angular/core';
2 |
3 | export function ɵcacheInstance(cacheKey: any, moduleName: string, appName: string, fn: () => T, deps: any): T {
4 | const [, instance, cachedDeps] = globalThis.ɵAngularfireInstanceCache.find((it: any) => it[0] === cacheKey) || [];
5 | if (instance) {
6 | if (!matchDep(deps, cachedDeps)) {
7 | log('error', `${moduleName} was already initialized on the ${appName} Firebase App with different settings.${IS_HMR ? ' You may need to reload as Firebase is not HMR aware.' : ''}`);
8 | log('warn', {is: deps, was: cachedDeps});
9 | }
10 | return instance;
11 | } else {
12 | const newInstance = fn();
13 | globalThis.ɵAngularfireInstanceCache.push([cacheKey, newInstance, deps]);
14 | return newInstance;
15 | }
16 | }
17 |
18 | function matchDep(a: any, b: any) {
19 | try {
20 | return a.toString() === b.toString();
21 | } catch (_) {
22 | return a === b;
23 | }
24 | }
25 |
26 | const IS_HMR = typeof module !== 'undefined' && !!(module as any).hot;
27 |
28 | const log = (level: 'log'|'error'|'info'|'warn', ...args: any) => {
29 | if (isDevMode() && typeof console !== 'undefined') {
30 | // eslint-disable-next-line no-console
31 | console[level](...args);
32 | }
33 | };
34 |
35 | globalThis.ɵAngularfireInstanceCache ||= [];
36 |
--------------------------------------------------------------------------------
/src/compat/database/database.module.ts:
--------------------------------------------------------------------------------
1 | import { NgModule } from '@angular/core';
2 | import { VERSION } from '@angular/fire';
3 | import firebase from 'firebase/compat/app';
4 | import { AngularFireDatabase } from './database';
5 |
6 | @NgModule({
7 | providers: [ AngularFireDatabase ]
8 | })
9 | export class AngularFireDatabaseModule {
10 | constructor() {
11 | firebase.registerVersion('angularfire', VERSION.full, 'rtdb-compat');
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/src/compat/database/list/data-operation.ts:
--------------------------------------------------------------------------------
1 | import { DatabaseReference, DatabaseSnapshot, FirebaseOperation } from '../interfaces';
2 | import { checkOperationCases } from '../utils';
3 |
4 | export function createDataOperationMethod(ref: DatabaseReference, operation: string) {
5 | return function dataOperation(item: FirebaseOperation, value: T) {
6 | return checkOperationCases(item, {
7 | stringCase: () => ref.child(item as string)[operation](value),
8 | firebaseCase: () => (item as DatabaseReference)[operation](value),
9 | snapshotCase: () => (item as DatabaseSnapshot).ref[operation](value)
10 | });
11 | };
12 | }
13 |
--------------------------------------------------------------------------------
/src/compat/database/list/remove.ts:
--------------------------------------------------------------------------------
1 | import { DatabaseReference, DatabaseSnapshot, FirebaseOperation } from '../interfaces';
2 | import { checkOperationCases } from '../utils';
3 |
4 | // TODO(davideast): Find out why TS thinks this returns firebase.Primise
5 | // instead of Promise.
6 | export function createRemoveMethod(ref: DatabaseReference) {
7 | return function remove(item?: FirebaseOperation): any {
8 | if (!item) { return ref.remove(); }
9 | return checkOperationCases(item, {
10 | stringCase: () => ref.child(item as string).remove(),
11 | firebaseCase: () => (item as DatabaseReference).remove(),
12 | snapshotCase: () => (item as DatabaseSnapshot).ref.remove()
13 | });
14 | };
15 | }
16 |
--------------------------------------------------------------------------------
/src/compat/database/list/snapshot-changes.ts:
--------------------------------------------------------------------------------
1 | import { Observable, SchedulerLike } from 'rxjs';
2 | import { ChildEvent, DatabaseQuery, SnapshotAction } from '../interfaces';
3 | import { listChanges } from './changes';
4 | import { validateEventsArray } from './utils';
5 |
6 | export function snapshotChanges(
7 | query: DatabaseQuery,
8 | events?: ChildEvent[],
9 | scheduler?: SchedulerLike
10 | ): Observable[]> {
11 | events = validateEventsArray(events);
12 | return listChanges(query, events, scheduler);
13 | }
14 |
--------------------------------------------------------------------------------
/src/compat/database/list/state-changes.ts:
--------------------------------------------------------------------------------
1 | import { SchedulerLike, merge } from 'rxjs';
2 | import { ChildEvent, DatabaseQuery } from '../interfaces';
3 | import { fromRef } from '../observable/fromRef';
4 | import { validateEventsArray } from './utils';
5 |
6 | export function stateChanges(query: DatabaseQuery, events?: ChildEvent[], scheduler?: SchedulerLike) {
7 | events = validateEventsArray(events);
8 | const childEvent$ = events.map(event => fromRef(query, event, 'on', scheduler));
9 | return merge(...childEvent$);
10 | }
11 |
--------------------------------------------------------------------------------
/src/compat/database/list/utils.ts:
--------------------------------------------------------------------------------
1 | import { isNil } from '../utils';
2 |
3 | export function validateEventsArray(events?: any[]) {
4 | if (isNil(events) || events.length === 0) {
5 | events = ['child_added', 'child_removed', 'child_changed', 'child_moved'];
6 | }
7 | return events;
8 | }
9 |
--------------------------------------------------------------------------------
/src/compat/database/ng-package.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "../../../node_modules/ng-packagr/ng-package.schema.json",
3 | "lib": {
4 | "entryFile": "public_api.ts"
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/src/compat/database/object/create-reference.ts:
--------------------------------------------------------------------------------
1 | import { Injector } from '@angular/core';
2 | import { pendingUntilEvent } from '@angular/core/rxjs-interop';
3 | import { map } from 'rxjs/operators';
4 | import { AngularFireDatabase } from '../database';
5 | import { AngularFireObject, DatabaseQuery } from '../interfaces';
6 | import { createObjectSnapshotChanges } from './snapshot-changes';
7 |
8 | export function createObjectReference(query: DatabaseQuery, afDatabase: AngularFireDatabase, injector?: Injector): AngularFireObject {
9 | return {
10 | query,
11 | snapshotChanges() {
12 | return createObjectSnapshotChanges(query, afDatabase.schedulers.outsideAngular)().pipe(
13 | pendingUntilEvent(injector)
14 | );
15 | },
16 | update(data: Partial) { return query.ref.update(data as any) as Promise; },
17 | set(data: T) { return query.ref.set(data) as Promise; },
18 | remove() { return query.ref.remove() as Promise; },
19 | valueChanges() {
20 | const snapshotChanges$ = createObjectSnapshotChanges(query, afDatabase.schedulers.outsideAngular)();
21 | return snapshotChanges$.pipe(
22 | pendingUntilEvent(injector),
23 | map(action => action.payload.exists() ? action.payload.val() as T : null)
24 | );
25 | },
26 | };
27 | }
28 |
--------------------------------------------------------------------------------
/src/compat/database/object/snapshot-changes.ts:
--------------------------------------------------------------------------------
1 | import { Observable, SchedulerLike } from 'rxjs';
2 | import { DatabaseQuery, SnapshotAction } from '../interfaces';
3 | import { fromRef } from '../observable/fromRef';
4 |
5 | export function createObjectSnapshotChanges(query: DatabaseQuery, scheduler?: SchedulerLike) {
6 | return function snapshotChanges(): Observable> {
7 | return fromRef(query, 'value', 'on', scheduler);
8 | };
9 | }
10 |
--------------------------------------------------------------------------------
/src/compat/database/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "../../node_modules/ng-packagr/package.schema.json"
3 | }
4 |
--------------------------------------------------------------------------------
/src/compat/database/public_api.ts:
--------------------------------------------------------------------------------
1 | export * from './database';
2 | export * from './list/changes';
3 | export * from './list/create-reference';
4 | export * from './list/snapshot-changes';
5 | export * from './list/state-changes';
6 | export * from './list/audit-trail';
7 | export * from './observable/fromRef';
8 | export * from './database.module';
9 |
--------------------------------------------------------------------------------
/src/compat/database/utils.spec.ts:
--------------------------------------------------------------------------------
1 | import * as utils from './utils';
2 |
3 | describe('utils', () => {
4 |
5 | describe('isString', () => {
6 |
7 | it('should be able to properly detect a string', () => {
8 | const str = 'oh hai';
9 | const notStr = 101;
10 | const bool = true;
11 | const nul = null;
12 | const obj = {};
13 | const fn = () => undefined;
14 | const undef = undefined;
15 | expect(utils.isString(str)).toBe(true);
16 | expect(utils.isString(notStr)).toBe(false);
17 | expect(utils.isString(bool)).toBe(false);
18 | expect(utils.isString(nul)).toBe(false);
19 | expect(utils.isString(obj)).toBe(false);
20 | expect(utils.isString(fn)).toBe(false);
21 | expect(utils.isString(undef)).toBe(false);
22 | });
23 |
24 | });
25 |
26 | });
27 |
--------------------------------------------------------------------------------
/src/compat/database/utils.ts:
--------------------------------------------------------------------------------
1 | import firebase from 'firebase/compat/app';
2 | import { DatabaseReference, FirebaseOperation, FirebaseOperationCases, PathReference } from './interfaces';
3 |
4 | export function isString(value: any): boolean {
5 | return typeof value === 'string';
6 | }
7 |
8 | export function isFirebaseDataSnapshot(value: any): boolean {
9 | return typeof value.exportVal === 'function';
10 | }
11 |
12 | export function isNil(obj: any): boolean {
13 | return obj === undefined || obj === null;
14 | }
15 |
16 | export function isFirebaseRef(value: any): boolean {
17 | return typeof value.set === 'function';
18 | }
19 |
20 | /**
21 | * Returns a database reference given a Firebase App and an
22 | * absolute or relative path.
23 | * @param database - Firebase Database
24 | * @param pathRef - Database path, relative or absolute
25 | */
26 | export function getRef(database: firebase.database.Database, pathRef: PathReference): DatabaseReference {
27 | // if a db ref was passed in, just return it
28 | return isFirebaseRef(pathRef) ? pathRef as DatabaseReference
29 | : database.ref(pathRef as string);
30 | }
31 |
32 | export function checkOperationCases(item: FirebaseOperation, cases: FirebaseOperationCases): Promise {
33 | if (isString(item)) {
34 | return cases.stringCase();
35 | } else if (isFirebaseRef(item)) {
36 | return cases.firebaseCase();
37 | } else if (isFirebaseDataSnapshot(item)) {
38 | return cases.snapshotCase();
39 | }
40 | throw new Error(`Expects a string, snapshot, or reference. Got: ${typeof item}`);
41 | }
42 |
--------------------------------------------------------------------------------
/src/compat/firebase.app.ts:
--------------------------------------------------------------------------------
1 | import firebase from 'firebase/compat/app';
2 |
3 | // eslint-disable-next-line @typescript-eslint/no-empty-interface
4 | export interface FirebaseApp extends firebase.app.App {}
5 |
6 | export class FirebaseApp {
7 | constructor(app: firebase.app.App) {
8 | return app;
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/src/compat/firestore/firestore.module.ts:
--------------------------------------------------------------------------------
1 | import { ModuleWithProviders, NgModule } from '@angular/core';
2 | import { VERSION } from '@angular/fire';
3 | import firebase from 'firebase/compat/app';
4 | import { AngularFirestore, ENABLE_PERSISTENCE, PERSISTENCE_SETTINGS } from './firestore';
5 | import { PersistenceSettings } from './interfaces';
6 |
7 | @NgModule({
8 | providers: [ AngularFirestore ]
9 | })
10 | export class AngularFirestoreModule {
11 | constructor() {
12 | firebase.registerVersion('angularfire', VERSION.full, 'fst-compat');
13 | }
14 | /**
15 | * Attempt to enable persistent storage, if possible
16 | */
17 | static enablePersistence(persistenceSettings?: PersistenceSettings): ModuleWithProviders {
18 | return {
19 | ngModule: AngularFirestoreModule,
20 | providers: [
21 | { provide: ENABLE_PERSISTENCE, useValue: true },
22 | { provide: PERSISTENCE_SETTINGS, useValue: persistenceSettings },
23 | ]
24 | };
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/src/compat/firestore/ng-package.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "../../../node_modules/ng-packagr/ng-package.schema.json",
3 | "lib": {
4 | "entryFile": "public_api.ts"
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/src/compat/firestore/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "../../node_modules/ng-packagr/package.schema.json"
3 | }
4 |
--------------------------------------------------------------------------------
/src/compat/firestore/public_api.ts:
--------------------------------------------------------------------------------
1 | export * from './firestore';
2 | export * from './firestore.module';
3 | export * from './collection/collection';
4 | export * from './collection-group/collection-group';
5 | export * from './document/document';
6 | export * from './collection/changes';
7 | export * from './observable/fromRef';
8 | export * from './interfaces';
9 |
--------------------------------------------------------------------------------
/src/compat/functions/base.ts:
--------------------------------------------------------------------------------
1 | // DO NOT MODIFY, this file is autogenerated by tools/build.ts
2 | // Export a null object with the same keys as firebase/compat/functions, so Proxy can work with proxy-polyfill in Internet Explorer
3 | export const proxyPolyfillCompat = {
4 | useEmulator: null,
5 | useFunctionsEmulator: null,
6 | httpsCallable: null,
7 | };
8 |
--------------------------------------------------------------------------------
/src/compat/functions/functions.module.ts:
--------------------------------------------------------------------------------
1 | import { NgModule } from '@angular/core';
2 | import { VERSION } from '@angular/fire';
3 | import firebase from 'firebase/compat/app';
4 | import { AngularFireFunctions } from './functions';
5 |
6 | @NgModule({
7 | providers: [ AngularFireFunctions ]
8 | })
9 | export class AngularFireFunctionsModule {
10 | constructor() {
11 | firebase.registerVersion('angularfire', VERSION.full, 'fn-compat');
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/src/compat/functions/ng-package.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "../../../node_modules/ng-packagr/ng-package.schema.json",
3 | "lib": {
4 | "entryFile": "public_api.ts"
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/src/compat/functions/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "../../node_modules/ng-packagr/package.schema.json"
3 | }
4 |
--------------------------------------------------------------------------------
/src/compat/functions/public_api.ts:
--------------------------------------------------------------------------------
1 |
2 | import 'firebase/compat/functions'; // removed in build process when not UMD
3 |
4 | export * from './functions';
5 | export * from './functions.module';
6 |
--------------------------------------------------------------------------------
/src/compat/messaging/base.ts:
--------------------------------------------------------------------------------
1 | // DO NOT MODIFY, this file is autogenerated by tools/build.ts
2 | // Export a null object with the same keys as firebase/compat/messaging, so Proxy can work with proxy-polyfill in Internet Explorer
3 | export const proxyPolyfillCompat = {
4 | deleteToken: null,
5 | getToken: null,
6 | onMessage: null,
7 | onBackgroundMessage: null,
8 | };
9 |
--------------------------------------------------------------------------------
/src/compat/messaging/messaging.module.ts:
--------------------------------------------------------------------------------
1 | import { NgModule } from '@angular/core';
2 | import { VERSION } from '@angular/fire';
3 | import firebase from 'firebase/compat/app';
4 | import { AngularFireMessaging } from './messaging';
5 |
6 | @NgModule({
7 | providers: [ AngularFireMessaging ]
8 | })
9 | export class AngularFireMessagingModule {
10 | constructor() {
11 | firebase.registerVersion('angularfire', VERSION.full, 'fcm-compat');
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/src/compat/messaging/ng-package.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "../../../node_modules/ng-packagr/ng-package.schema.json",
3 | "lib": {
4 | "entryFile": "public_api.ts"
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/src/compat/messaging/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "../../node_modules/ng-packagr/package.schema.json"
3 | }
4 |
--------------------------------------------------------------------------------
/src/compat/messaging/public_api.ts:
--------------------------------------------------------------------------------
1 | export * from './messaging';
2 | export * from './messaging.module';
3 |
--------------------------------------------------------------------------------
/src/compat/ng-package.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "../../node_modules/ng-packagr/ng-package.schema.json",
3 | "lib": {
4 | "entryFile": "public_api.ts"
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/src/compat/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "../../node_modules/ng-packagr/package.schema.json"
3 | }
4 |
--------------------------------------------------------------------------------
/src/compat/performance/base.ts:
--------------------------------------------------------------------------------
1 | // DO NOT MODIFY, this file is autogenerated by tools/build.ts
2 | // Export a null object with the same keys as firebase/compat/performance, so Proxy can work with proxy-polyfill in Internet Explorer
3 | export const proxyPolyfillCompat = {
4 | app: null,
5 | trace: null,
6 | instrumentationEnabled: null,
7 | dataCollectionEnabled: null,
8 | };
9 |
--------------------------------------------------------------------------------
/src/compat/performance/ng-package.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "../../../node_modules/ng-packagr/ng-package.schema.json",
3 | "lib": {
4 | "entryFile": "public_api.ts"
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/src/compat/performance/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "../../node_modules/ng-packagr/package.schema.json"
3 | }
4 |
--------------------------------------------------------------------------------
/src/compat/performance/performance.module.ts:
--------------------------------------------------------------------------------
1 | import { NgModule, Optional } from '@angular/core';
2 | import { VERSION } from '@angular/fire';
3 | import firebase from 'firebase/compat/app';
4 | import { AngularFirePerformance } from './performance';
5 | import { PerformanceMonitoringService } from './performance.service';
6 |
7 | @NgModule({
8 | providers: [ AngularFirePerformance ]
9 | })
10 | export class AngularFirePerformanceModule {
11 | constructor(
12 | perf: AngularFirePerformance,
13 | @Optional() _: PerformanceMonitoringService
14 | ) {
15 | firebase.registerVersion('angularfire', VERSION.full, 'perf-compat');
16 | // call anything here to get perf loading
17 | perf.dataCollectionEnabled.then(() => undefined);
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/src/compat/performance/performance.service.ts:
--------------------------------------------------------------------------------
1 | import { ApplicationRef, Injectable, OnDestroy } from '@angular/core';
2 | import { Subscription } from 'rxjs';
3 | import { first, tap } from 'rxjs/operators';
4 |
5 | const IS_STABLE_START_MARK = 'Zone';
6 | const IS_STABLE_END_MARK = '_isStableEnd';
7 |
8 | @Injectable()
9 | export class PerformanceMonitoringService implements OnDestroy {
10 |
11 | private disposable: Subscription|undefined;
12 |
13 | constructor(appRef: ApplicationRef) {
14 | // eslint-disable-next-line @typescript-eslint/prefer-optional-chain
15 | if (typeof window !== 'undefined' && window.performance?.mark) {
16 | this.disposable = appRef.isStable.pipe(
17 | first(it => it),
18 | tap(() => {
19 | window.performance.mark(IS_STABLE_END_MARK);
20 | window.performance.measure('isStable', IS_STABLE_START_MARK, IS_STABLE_END_MARK);
21 | })
22 | ).subscribe();
23 | }
24 | }
25 |
26 | ngOnDestroy() {
27 | if (this.disposable) { this.disposable.unsubscribe(); }
28 | }
29 |
30 | }
31 |
--------------------------------------------------------------------------------
/src/compat/performance/performance.spec.ts:
--------------------------------------------------------------------------------
1 | import { TestBed } from '@angular/core/testing';
2 | import { AngularFireModule } from '@angular/fire/compat';
3 | import { AngularFirePerformance, AngularFirePerformanceModule } from '@angular/fire/compat/performance';
4 | import { COMMON_CONFIG } from '../../../src/test-config';
5 |
6 | describe('AngularFirePerformance', () => {
7 | let afp: AngularFirePerformance;
8 |
9 | beforeEach(() => {
10 | TestBed.configureTestingModule({
11 | imports: [
12 | // NOTE: You must use the [DEFAULT] app instance
13 | // for these tests to work.
14 | AngularFireModule.initializeApp(COMMON_CONFIG),
15 | AngularFirePerformanceModule
16 | ]
17 | });
18 | afp = TestBed.inject(AngularFirePerformance);
19 | });
20 |
21 | it('should exist', () => {
22 | expect(afp instanceof AngularFirePerformance).toBe(true);
23 | });
24 |
25 | it('should have the Performance instance', () => {
26 | expect(afp.dataCollectionEnabled).toBeDefined();
27 | });
28 |
29 | });
30 |
--------------------------------------------------------------------------------
/src/compat/performance/public_api.ts:
--------------------------------------------------------------------------------
1 | export * from './performance';
2 | export * from './performance.module';
3 | export * from './performance.service';
4 |
--------------------------------------------------------------------------------
/src/compat/public_api.ts:
--------------------------------------------------------------------------------
1 | export * from './proxy';
2 | export * from './firebase.app';
3 | export * from './firebase.app.module';
4 | export * from './cache';
5 |
--------------------------------------------------------------------------------
/src/compat/remote-config/base.ts:
--------------------------------------------------------------------------------
1 | // DO NOT MODIFY, this file is autogenerated by tools/build.ts
2 | // Export a null object with the same keys as firebase/compat/remote-config, so Proxy can work with proxy-polyfill in Internet Explorer
3 | export const proxyPolyfillCompat = {
4 | app: null,
5 | settings: null,
6 | defaultConfig: null,
7 | fetchTimeMillis: null,
8 | lastFetchStatus: null,
9 | activate: null,
10 | ensureInitialized: null,
11 | fetch: null,
12 | fetchAndActivate: null,
13 | getAll: null,
14 | getBoolean: null,
15 | getNumber: null,
16 | getString: null,
17 | getValue: null,
18 | setLogLevel: null,
19 | };
20 |
--------------------------------------------------------------------------------
/src/compat/remote-config/index.ts:
--------------------------------------------------------------------------------
1 | export * from './public_api';
2 |
--------------------------------------------------------------------------------
/src/compat/remote-config/interfaces.ts:
--------------------------------------------------------------------------------
1 | import firebase from 'firebase/compat/app';
2 |
3 | export type Settings = firebase.remoteConfig.Settings;
4 |
--------------------------------------------------------------------------------
/src/compat/remote-config/ng-package.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "../../../node_modules/ng-packagr/ng-package.schema.json",
3 | "lib": {
4 | "entryFile": "public_api.ts"
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/src/compat/remote-config/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "../../node_modules/ng-packagr/package.schema.json"
3 | }
4 |
--------------------------------------------------------------------------------
/src/compat/remote-config/public_api.ts:
--------------------------------------------------------------------------------
1 | export * from './remote-config';
2 | export * from './remote-config.module';
3 |
--------------------------------------------------------------------------------
/src/compat/remote-config/remote-config.module.ts:
--------------------------------------------------------------------------------
1 | import { NgModule } from '@angular/core';
2 | import { VERSION } from '@angular/fire';
3 | import firebase from 'firebase/compat/app';
4 | import { AngularFireRemoteConfig } from './remote-config';
5 |
6 | @NgModule({
7 | providers: [ AngularFireRemoteConfig ]
8 | })
9 | export class AngularFireRemoteConfigModule {
10 | constructor() {
11 | firebase.registerVersion('angularfire', VERSION.full, 'rc-compat');
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/src/compat/storage/interfaces.ts:
--------------------------------------------------------------------------------
1 | import firebase from 'firebase/compat/app';
2 |
3 | export type UploadTask = firebase.storage.UploadTask;
4 | export type UploadTaskSnapshot = firebase.storage.UploadTaskSnapshot;
5 | export type UploadMetadata = firebase.storage.UploadMetadata;
6 |
7 | export type SettableMetadata = firebase.storage.SettableMetadata;
8 | export type Reference = firebase.storage.Reference;
9 | export type StringFormat = firebase.storage.StringFormat;
10 | export type ListResult = firebase.storage.ListResult;
11 | export type ListOptions = firebase.storage.ListOptions;
12 |
--------------------------------------------------------------------------------
/src/compat/storage/ng-package.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "../../../node_modules/ng-packagr/ng-package.schema.json",
3 | "lib": {
4 | "entryFile": "public_api.ts"
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/src/compat/storage/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "../../node_modules/ng-packagr/package.schema.json"
3 | }
4 |
--------------------------------------------------------------------------------
/src/compat/storage/pipes/storageUrl.pipe.ts:
--------------------------------------------------------------------------------
1 | import { AsyncPipe } from '@angular/common';
2 | import { ChangeDetectorRef, NgModule, OnDestroy, Optional, Pipe, PipeTransform, TransferState, makeStateKey } from '@angular/core';
3 | import { Observable, of } from 'rxjs';
4 | import { tap } from 'rxjs/operators';
5 | import { AngularFireStorage } from '../storage';
6 |
7 | /** to be used with in combination with | async */
8 | @Pipe({
9 | name: 'getDownloadURL',
10 | pure: false,
11 | })
12 | export class GetDownloadURLPipe implements PipeTransform, OnDestroy {
13 |
14 | private asyncPipe: AsyncPipe;
15 | private path: string;
16 | private downloadUrl$: Observable;
17 |
18 | constructor(
19 | private storage: AngularFireStorage,
20 | cdr: ChangeDetectorRef,
21 | @Optional() private state: TransferState
22 | ) {
23 | this.asyncPipe = new AsyncPipe(cdr);
24 | }
25 |
26 | transform(path: string) {
27 | if (path !== this.path) {
28 | this.path = path;
29 | const key = makeStateKey(`|getDownloadURL|${path}`);
30 | const existing = this.state?.get(key, undefined);
31 | this.downloadUrl$ = existing ? of(existing) : this.storage.ref(path).getDownloadURL().pipe(
32 | tap(it => this.state?.set(key, it))
33 | );
34 | }
35 | return this.asyncPipe.transform(this.downloadUrl$);
36 | }
37 |
38 | ngOnDestroy() {
39 | this.asyncPipe.ngOnDestroy();
40 | }
41 |
42 | }
43 |
44 | @NgModule({
45 | imports: [ GetDownloadURLPipe ],
46 | exports: [ GetDownloadURLPipe ],
47 | })
48 | export class GetDownloadURLPipeModule {}
49 |
--------------------------------------------------------------------------------
/src/compat/storage/public_api.ts:
--------------------------------------------------------------------------------
1 | export * from './ref';
2 | export * from './storage';
3 | export * from './task';
4 | export * from './observable/fromTask';
5 | export * from './storage.module';
6 | export * from './pipes/storageUrl.pipe';
7 |
--------------------------------------------------------------------------------
/src/compat/storage/storage.module.ts:
--------------------------------------------------------------------------------
1 | import { NgModule } from '@angular/core';
2 | import { VERSION } from '@angular/fire';
3 | import firebase from 'firebase/compat/app';
4 | import { GetDownloadURLPipeModule } from './pipes/storageUrl.pipe';
5 | import { AngularFireStorage } from './storage';
6 |
7 | @NgModule({
8 | imports: [ GetDownloadURLPipeModule ],
9 | exports: [ GetDownloadURLPipeModule ],
10 | providers: [ AngularFireStorage ]
11 | })
12 | export class AngularFireStorageModule {
13 | constructor() {
14 | firebase.registerVersion('angularfire', VERSION.full, 'gcs-compat');
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/src/compat/storage/task.ts:
--------------------------------------------------------------------------------
1 | import { Observable } from 'rxjs';
2 | import { map } from 'rxjs/operators';
3 | import { UploadTask, UploadTaskSnapshot } from './interfaces';
4 | import { fromTask } from './observable/fromTask';
5 |
6 | export interface AngularFireUploadTask {
7 | task: UploadTask;
8 | snapshotChanges(): Observable;
9 | percentageChanges(): Observable;
10 | pause(): boolean;
11 | cancel(): boolean;
12 | resume(): boolean;
13 | then(
14 | onFulfilled?: ((a: UploadTaskSnapshot) => any) | null,
15 | onRejected?: ((a: Error) => any) | null
16 | ): Promise;
17 | catch(onRejected: (a: Error) => any): Promise;
18 | }
19 |
20 | /**
21 | * Create an AngularFireUploadTask from a regular UploadTask from the Storage SDK.
22 | * This method creates an observable of the upload and returns on object that provides
23 | * multiple methods for controlling and monitoring the file upload.
24 | */
25 | export function createUploadTask(task: UploadTask): AngularFireUploadTask {
26 | const inner$ = fromTask(task);
27 | return {
28 | task,
29 | then: task.then.bind(task),
30 | catch: task.catch.bind(task),
31 | pause: task.pause.bind(task),
32 | cancel: task.cancel.bind(task),
33 | resume: task.resume.bind(task),
34 | snapshotChanges: () => inner$,
35 | percentageChanges: () => inner$.pipe(
36 | map(s => s.bytesTransferred / s.totalBytes * 100)
37 | )
38 | };
39 | }
40 |
--------------------------------------------------------------------------------
/src/data-connect/data-connect.spec.ts:
--------------------------------------------------------------------------------
1 | /*
2 | import { TestBed } from '@angular/core/testing';
3 | import { getApp, initializeApp, provideFirebaseApp } from '@angular/fire/app';
4 | import { DataConnect, getDataConnect, provideDataConnect } from '@angular/fire/data-connect';
5 | import { COMMON_CONFIG } from '../test-config';
6 | import { rando } from '../utils';
7 |
8 |
9 | describe('DataConnect', () => {
10 | let dataConnect: DataConnect;
11 | let providedDataConnect: DataConnect;
12 | let appName: string;
13 |
14 | describe('single injection', () => {
15 |
16 | beforeEach(() => {
17 | appName = rando();
18 | TestBed.configureTestingModule({
19 | providers: [
20 | provideFirebaseApp(() => initializeApp(COMMON_CONFIG, appName)),
21 | provideDataConnect(() => {
22 | providedDataConnect = getDataConnect(getApp(appName));
23 | return providedDataConnect;
24 | }),
25 | ],
26 | });
27 | dataConnect = TestBed.inject(DataConnect);
28 | });
29 |
30 | it('should be injectable', () => {
31 | expect(providedDataConnect).toBeTruthy();
32 | expect(dataConnect).toEqual(providedDataConnect);
33 | });
34 |
35 | });
36 |
37 | });
38 | */
--------------------------------------------------------------------------------
/src/data-connect/data-connect.ts:
--------------------------------------------------------------------------------
1 | import { ɵgetAllInstancesOf } from '@angular/fire';
2 | import { DataConnect } from 'firebase/data-connect';
3 | import { from, timer } from 'rxjs';
4 | import { concatMap, distinct } from 'rxjs/operators';
5 |
6 | export { DataConnect };
7 |
8 | export const DATA_CONNECT_PROVIDER_NAME = 'data-connect';
9 |
10 | // eslint-disable-next-line @typescript-eslint/no-empty-interface
11 | export interface DataConnectInstances extends Array {}
12 |
13 | export class DataConnectInstances {
14 | constructor() {
15 | return ɵgetAllInstancesOf(DATA_CONNECT_PROVIDER_NAME);
16 | }
17 | }
18 |
19 | export const dataConnectInstance$ = timer(0, 300).pipe(
20 | concatMap(() => from(ɵgetAllInstancesOf(DATA_CONNECT_PROVIDER_NAME))),
21 | distinct(),
22 | );
23 |
--------------------------------------------------------------------------------
/src/data-connect/firebase.ts:
--------------------------------------------------------------------------------
1 | // DO NOT MODIFY, this file is autogenerated by tools/build.ts
2 | export * from 'firebase/data-connect';
3 | import { ɵzoneWrap } from '@angular/fire';
4 | import {
5 | connectDataConnectEmulator as _connectDataConnectEmulator,
6 | executeMutation as _executeMutation,
7 | executeQuery as _executeQuery,
8 | getDataConnect as _getDataConnect,
9 | mutationRef as _mutationRef,
10 | queryRef as _queryRef,
11 | setLogLevel as _setLogLevel,
12 | subscribe as _subscribe,
13 | terminate as _terminate,
14 | toQueryRef as _toQueryRef
15 | } from 'firebase/data-connect';
16 |
17 | export const connectDataConnectEmulator = ɵzoneWrap(_connectDataConnectEmulator, true);
18 | export const executeMutation = ɵzoneWrap(_executeMutation, true);
19 | export const executeQuery = ɵzoneWrap(_executeQuery, true);
20 | export const getDataConnect = ɵzoneWrap(_getDataConnect, true);
21 | export const mutationRef = ɵzoneWrap(_mutationRef, true, 2);
22 | export const queryRef = ɵzoneWrap(_queryRef, true, 2);
23 | export const setLogLevel = ɵzoneWrap(_setLogLevel, true);
24 | export const subscribe = ɵzoneWrap(_subscribe, true);
25 | export const terminate = ɵzoneWrap(_terminate, true);
26 | export const toQueryRef = ɵzoneWrap(_toQueryRef, true, 2);
27 |
--------------------------------------------------------------------------------
/src/data-connect/ng-package.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "../../node_modules/ng-packagr/ng-package.schema.json",
3 | "lib": {
4 | "entryFile": "public_api.ts"
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/src/data-connect/overrides.ts:
--------------------------------------------------------------------------------
1 | import { isMessagingSupportedFactory } from './is-messaging-supported-factory';
2 |
3 | export const isSupported = isMessagingSupportedFactory.async;
4 |
--------------------------------------------------------------------------------
/src/data-connect/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "../../node_modules/ng-packagr/package.schema.json"
3 | }
4 |
--------------------------------------------------------------------------------
/src/data-connect/public_api.ts:
--------------------------------------------------------------------------------
1 | export { DataConnectInstances, DataConnect, dataConnectInstance$ } from './data-connect';
2 | export { provideDataConnect, DataConnectModule } from './data-connect.module';
3 | export * from './firebase';
4 |
--------------------------------------------------------------------------------
/src/database/database.spec.ts:
--------------------------------------------------------------------------------
1 | import { TestBed } from '@angular/core/testing';
2 | import { FirebaseApp, getApp, initializeApp, provideFirebaseApp } from '@angular/fire/app';
3 | import { Database, connectDatabaseEmulator, getDatabase, provideDatabase } from '@angular/fire/database';
4 | import { COMMON_CONFIG } from '../test-config';
5 | import { rando } from '../utils';
6 |
7 | describe('Database', () => {
8 | let app: FirebaseApp;
9 | let database: Database;
10 | let providedDatabase: Database;
11 | let appName: string;
12 |
13 | describe('single injection', () => {
14 |
15 | beforeEach(() => {
16 | appName = rando();
17 | TestBed.configureTestingModule({
18 | providers: [
19 | provideFirebaseApp(() => initializeApp(COMMON_CONFIG, appName)),
20 | provideDatabase(() => {
21 | providedDatabase = getDatabase(getApp(appName));
22 | connectDatabaseEmulator(providedDatabase, 'localhost', 9002);
23 | return providedDatabase;
24 | }),
25 | ],
26 | });
27 | app = TestBed.inject(FirebaseApp);
28 | database = TestBed.inject(Database);
29 | });
30 |
31 | it('should be injectable', () => {
32 | expect(providedDatabase).toBeTruthy();
33 | expect(database).toEqual(providedDatabase);
34 | expect(database.app).toEqual(app);
35 | });
36 |
37 | });
38 |
39 | });
40 |
--------------------------------------------------------------------------------
/src/database/database.ts:
--------------------------------------------------------------------------------
1 | import { ɵgetAllInstancesOf } from '@angular/fire';
2 | import { Database as FirebaseDatabase } from 'firebase/database';
3 | import { from, timer } from 'rxjs';
4 | import { concatMap, distinct } from 'rxjs/operators';
5 |
6 | // see notes in core/firebase.app.module.ts for why we're building the class like this
7 | // eslint-disable-next-line @typescript-eslint/no-empty-interface
8 | export interface Database extends FirebaseDatabase {}
9 |
10 | export class Database {
11 | constructor(database: FirebaseDatabase) {
12 | return database;
13 | }
14 | }
15 |
16 | export const DATABASE_PROVIDER_NAME = 'database';
17 |
18 | // eslint-disable-next-line @typescript-eslint/no-empty-interface
19 | export interface DatabaseInstances extends Array {}
20 |
21 | export class DatabaseInstances {
22 | constructor() {
23 | return ɵgetAllInstancesOf(DATABASE_PROVIDER_NAME);
24 | }
25 | }
26 |
27 | export const databaseInstance$ = timer(0, 300).pipe(
28 | concatMap(() => from(ɵgetAllInstancesOf(DATABASE_PROVIDER_NAME))),
29 | distinct(),
30 | );
31 |
--------------------------------------------------------------------------------
/src/database/ng-package.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "../../node_modules/ng-packagr/ng-package.schema.json",
3 | "lib": {
4 | "entryFile": "public_api.ts"
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/src/database/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "../../node_modules/ng-packagr/package.schema.json"
3 | }
4 |
--------------------------------------------------------------------------------
/src/database/public_api.ts:
--------------------------------------------------------------------------------
1 | export { Database, DatabaseInstances, databaseInstance$ } from './database';
2 | export { provideDatabase, DatabaseModule } from './database.module';
3 | export * from './rxfire';
4 | export * from './firebase';
5 |
--------------------------------------------------------------------------------
/src/database/rxfire.ts:
--------------------------------------------------------------------------------
1 | // DO NOT MODIFY, this file is autogenerated by tools/build.ts
2 | import { ɵzoneWrap } from '@angular/fire';
3 | import {
4 | auditTrail as _auditTrail,
5 | changeToData as _changeToData,
6 | fromRef as _fromRef,
7 | list as _list,
8 | listVal as _listVal,
9 | object as _object,
10 | objectVal as _objectVal,
11 | stateChanges as _stateChanges
12 | } from 'rxfire/database';
13 |
14 | export {
15 | ListenEvent,
16 | ListenerMethods
17 | } from 'rxfire/database';
18 |
19 | export const auditTrail = ɵzoneWrap(_auditTrail, true);
20 | export const changeToData = ɵzoneWrap(_changeToData, true);
21 | export const fromRef = ɵzoneWrap(_fromRef, true);
22 | export const list = ɵzoneWrap(_list, true);
23 | export const listVal = ɵzoneWrap(_listVal, true);
24 | export const object = ɵzoneWrap(_object, true);
25 | export const objectVal = ɵzoneWrap(_objectVal, true);
26 | export const stateChanges = ɵzoneWrap(_stateChanges, true);
27 |
--------------------------------------------------------------------------------
/src/firestore/firestore.spec.ts:
--------------------------------------------------------------------------------
1 | import { TestBed } from '@angular/core/testing';
2 | import { FirebaseApp, getApp, initializeApp, provideFirebaseApp } from '@angular/fire/app';
3 | import { Firestore, connectFirestoreEmulator, getFirestore, provideFirestore } from '@angular/fire/firestore';
4 | import { COMMON_CONFIG, firestoreEmulatorPort } from '../test-config';
5 | import { rando } from '../utils';
6 |
7 | describe('Firestore', () => {
8 | let app: FirebaseApp;
9 | let firestore: Firestore;
10 | let providedFirestore: Firestore;
11 | let appName: string;
12 |
13 | describe('single injection', () => {
14 |
15 | beforeEach(() => {
16 | appName = rando();
17 | TestBed.configureTestingModule({
18 | providers: [
19 | provideFirebaseApp(() => initializeApp(COMMON_CONFIG, appName)),
20 | provideFirestore(() => {
21 | providedFirestore = getFirestore(getApp(appName));
22 | connectFirestoreEmulator(providedFirestore, 'localhost', firestoreEmulatorPort);
23 | return providedFirestore;
24 | }),
25 | ],
26 | });
27 | app = TestBed.inject(FirebaseApp);
28 | firestore = TestBed.inject(Firestore);
29 | });
30 |
31 | it('should be injectable', () => {
32 | expect(providedFirestore).toBeTruthy();
33 | expect(firestore).toEqual(providedFirestore);
34 | expect(firestore.app).toEqual(app);
35 | });
36 |
37 | });
38 |
39 | });
40 |
--------------------------------------------------------------------------------
/src/firestore/firestore.ts:
--------------------------------------------------------------------------------
1 | import { ɵgetAllInstancesOf } from '@angular/fire';
2 | import { Firestore as FirebaseFirestore } from 'firebase/firestore';
3 | import { from, timer } from 'rxjs';
4 | import { concatMap, distinct } from 'rxjs/operators';
5 |
6 | // see notes in core/firebase.app.module.ts for why we're building the class like this
7 | // eslint-disable-next-line @typescript-eslint/no-empty-interface
8 | export interface Firestore extends FirebaseFirestore {}
9 |
10 | export class Firestore {
11 | constructor(firestore: FirebaseFirestore) {
12 | return firestore;
13 | }
14 | }
15 |
16 | export const FIRESTORE_PROVIDER_NAME = 'firestore';
17 |
18 | // eslint-disable-next-line @typescript-eslint/no-empty-interface
19 | export interface FirestoreInstances extends Array {}
20 |
21 | export class FirestoreInstances {
22 | constructor() {
23 | return ɵgetAllInstancesOf(FIRESTORE_PROVIDER_NAME);
24 | }
25 | }
26 |
27 | export const firestoreInstance$ = timer(0, 300).pipe(
28 | concatMap(() => from(ɵgetAllInstancesOf(FIRESTORE_PROVIDER_NAME))),
29 | distinct(),
30 | );
31 |
--------------------------------------------------------------------------------
/src/firestore/lite/lite.spec.ts:
--------------------------------------------------------------------------------
1 | import { TestBed } from '@angular/core/testing';
2 | import { FirebaseApp, getApp, initializeApp, provideFirebaseApp } from '@angular/fire/app';
3 | import { Firestore, connectFirestoreEmulator, getFirestore, provideFirestore } from '@angular/fire/firestore/lite';
4 | import { COMMON_CONFIG, firestoreEmulatorPort } from '../../test-config';
5 | import { rando } from '../../utils';
6 |
7 | describe('Firestore-lite', () => {
8 | let app: FirebaseApp;
9 | let firestore: Firestore;
10 | let providedFirestore: Firestore;
11 | let appName: string;
12 |
13 | describe('single injection', () => {
14 |
15 | beforeEach(() => {
16 | appName = rando();
17 | TestBed.configureTestingModule({
18 | providers: [
19 | provideFirebaseApp(() => initializeApp(COMMON_CONFIG, appName)),
20 | provideFirestore(() => {
21 | providedFirestore = getFirestore(getApp(appName));
22 | connectFirestoreEmulator(providedFirestore, 'localhost', firestoreEmulatorPort);
23 | return providedFirestore;
24 | }),
25 | ],
26 | });
27 | app = TestBed.inject(FirebaseApp);
28 | firestore = TestBed.inject(Firestore);
29 | });
30 |
31 | it('should be injectable', () => {
32 | expect(providedFirestore).toBeTruthy();
33 | expect(firestore).toEqual(providedFirestore);
34 | expect(firestore.app).toEqual(app);
35 | });
36 |
37 | });
38 |
39 | });
40 |
--------------------------------------------------------------------------------
/src/firestore/lite/lite.ts:
--------------------------------------------------------------------------------
1 | import { ɵgetAllInstancesOf } from '@angular/fire';
2 | import { Firestore as FirebaseFirestore } from 'firebase/firestore/lite';
3 | import { from, timer } from 'rxjs';
4 | import { concatMap, distinct } from 'rxjs/operators';
5 |
6 | // see notes in core/firebase.app.module.ts for why we're building the class like this
7 | // eslint-disable-next-line @typescript-eslint/no-empty-interface
8 | export interface Firestore extends FirebaseFirestore {}
9 |
10 | export class Firestore {
11 | constructor(firestore: FirebaseFirestore) {
12 | return firestore;
13 | }
14 | }
15 |
16 | export const FIRESTORE_PROVIDER_NAME = 'firestore/lite';
17 |
18 | // eslint-disable-next-line @typescript-eslint/no-empty-interface
19 | export interface FirestoreInstances extends Array {}
20 |
21 | export class FirestoreInstances {
22 | constructor() {
23 | return ɵgetAllInstancesOf(FIRESTORE_PROVIDER_NAME);
24 | }
25 | }
26 |
27 | export const firestoreInstance$ = timer(0, 300).pipe(
28 | concatMap(() => from(ɵgetAllInstancesOf(FIRESTORE_PROVIDER_NAME))),
29 | distinct(),
30 | );
31 |
--------------------------------------------------------------------------------
/src/firestore/lite/ng-package.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "../../node_modules/ng-packagr/ng-package.schema.json",
3 | "lib": {
4 | "entryFile": "public_api.ts"
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/src/firestore/lite/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "../../../node_modules/ng-packagr/package.schema.json"
3 | }
4 |
--------------------------------------------------------------------------------
/src/firestore/lite/public_api.ts:
--------------------------------------------------------------------------------
1 | export { Firestore, FirestoreInstances, firestoreInstance$ } from './lite';
2 | export { FirestoreModule, provideFirestore } from './lite.module';
3 | export * from './rxfire';
4 | export * from './firebase';
5 |
--------------------------------------------------------------------------------
/src/firestore/lite/rxfire.ts:
--------------------------------------------------------------------------------
1 | // DO NOT MODIFY, this file is autogenerated by tools/build.ts
2 | import { ɵzoneWrap } from '@angular/fire';
3 | import {
4 | collection as _collection,
5 | collectionCount as _collectionCount,
6 | collectionCountSnap as _collectionCountSnap,
7 | collectionData as _collectionData,
8 | doc as _doc,
9 | docData as _docData,
10 | fromRef as _fromRef,
11 | snapToData as _snapToData
12 | } from 'rxfire/firestore/lite';
13 |
14 | export const collectionSnapshots = ɵzoneWrap(_collection, true);
15 | export const collectionCount = ɵzoneWrap(_collectionCount, true);
16 | export const collectionCountSnap = ɵzoneWrap(_collectionCountSnap, true);
17 | export const collectionData = ɵzoneWrap(_collectionData, true);
18 | export const docSnapshots = ɵzoneWrap(_doc, true);
19 | export const docData = ɵzoneWrap(_docData, true);
20 | export const fromRef = ɵzoneWrap(_fromRef, true);
21 | export const snapToData = ɵzoneWrap(_snapToData, true);
22 |
--------------------------------------------------------------------------------
/src/firestore/ng-package.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "../../node_modules/ng-packagr/ng-package.schema.json",
3 | "lib": {
4 | "entryFile": "public_api.ts"
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/src/firestore/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "../../node_modules/ng-packagr/package.schema.json"
3 | }
4 |
--------------------------------------------------------------------------------
/src/firestore/public_api.ts:
--------------------------------------------------------------------------------
1 | export { Firestore, FirestoreInstances, firestoreInstance$ } from './firestore';
2 | export { provideFirestore, FirestoreModule } from './firestore.module';
3 | export * from './rxfire';
4 | export * from './firebase';
5 |
--------------------------------------------------------------------------------
/src/firestore/rxfire.ts:
--------------------------------------------------------------------------------
1 | // DO NOT MODIFY, this file is autogenerated by tools/build.ts
2 | import { ɵzoneWrap } from '@angular/fire';
3 | import {
4 | auditTrail as _auditTrail,
5 | collection as _collection,
6 | collectionChanges as _collectionChanges,
7 | collectionCount as _collectionCount,
8 | collectionCountSnap as _collectionCountSnap,
9 | collectionData as _collectionData,
10 | doc as _doc,
11 | docData as _docData,
12 | fromRef as _fromRef,
13 | snapToData as _snapToData,
14 | sortedChanges as _sortedChanges
15 | } from 'rxfire/firestore';
16 |
17 | export const auditTrail = ɵzoneWrap(_auditTrail, true);
18 | export const collectionSnapshots = ɵzoneWrap(_collection, true);
19 | export const collectionChanges = ɵzoneWrap(_collectionChanges, true);
20 | export const collectionCount = ɵzoneWrap(_collectionCount, true);
21 | export const collectionCountSnap = ɵzoneWrap(_collectionCountSnap, true);
22 | export const collectionData = ɵzoneWrap(_collectionData, true);
23 | export const docSnapshots = ɵzoneWrap(_doc, true);
24 | export const docData = ɵzoneWrap(_docData, true);
25 | export const fromRef = ɵzoneWrap(_fromRef, true);
26 | export const snapToData = ɵzoneWrap(_snapToData, true);
27 | export const sortedChanges = ɵzoneWrap(_sortedChanges, true);
28 |
--------------------------------------------------------------------------------
/src/functions/firebase.ts:
--------------------------------------------------------------------------------
1 | // DO NOT MODIFY, this file is autogenerated by tools/build.ts
2 | export * from 'firebase/functions';
3 | import { ɵzoneWrap } from '@angular/fire';
4 | import {
5 | connectFunctionsEmulator as _connectFunctionsEmulator,
6 | getFunctions as _getFunctions,
7 | httpsCallable as _httpsCallable,
8 | httpsCallableFromURL as _httpsCallableFromURL
9 | } from 'firebase/functions';
10 |
11 | export const connectFunctionsEmulator = ɵzoneWrap(_connectFunctionsEmulator, true);
12 | export const getFunctions = ɵzoneWrap(_getFunctions, true);
13 | export const httpsCallable = ɵzoneWrap(_httpsCallable, true);
14 | export const httpsCallableFromURL = ɵzoneWrap(_httpsCallableFromURL, true);
15 |
--------------------------------------------------------------------------------
/src/functions/functions.spec.ts:
--------------------------------------------------------------------------------
1 | import { TestBed } from '@angular/core/testing';
2 | import { FirebaseApp, getApp, initializeApp, provideFirebaseApp } from '@angular/fire/app';
3 | import { Functions, connectFunctionsEmulator, getFunctions, provideFunctions } from '@angular/fire/functions';
4 | import { COMMON_CONFIG, functionsEmulatorPort } from '../test-config';
5 | import { rando } from '../utils';
6 |
7 | describe('Functions', () => {
8 | let app: FirebaseApp;
9 | let functions: Functions;
10 | let providedFunctions: Functions;
11 | let appName: string;
12 |
13 | describe('single injection', () => {
14 |
15 | beforeEach(() => {
16 | appName = rando();
17 | TestBed.configureTestingModule({
18 | providers: [
19 | provideFirebaseApp(() => initializeApp(COMMON_CONFIG, appName)),
20 | provideFunctions(() => {
21 | providedFunctions = getFunctions(getApp(appName));
22 | connectFunctionsEmulator(providedFunctions, 'localhost', functionsEmulatorPort);
23 | return providedFunctions;
24 | }),
25 | ],
26 | });
27 | app = TestBed.inject(FirebaseApp);
28 | functions = TestBed.inject(Functions);
29 | });
30 |
31 | it('should be injectable', () => {
32 | expect(providedFunctions).toBeTruthy();
33 | expect(functions).toEqual(providedFunctions);
34 | expect(functions.app).toEqual(app);
35 | });
36 |
37 | });
38 |
39 | });
40 |
--------------------------------------------------------------------------------
/src/functions/functions.ts:
--------------------------------------------------------------------------------
1 | import { ɵgetAllInstancesOf } from '@angular/fire';
2 | import { Functions as FirebaseFunctions } from 'firebase/functions';
3 | import { from, timer } from 'rxjs';
4 | import { concatMap, distinct } from 'rxjs/operators';
5 |
6 | // see notes in core/firebase.app.module.ts for why we're building the class like this
7 | // eslint-disable-next-line @typescript-eslint/no-empty-interface
8 | export interface Functions extends FirebaseFunctions {}
9 |
10 | export class Functions {
11 | constructor(functions: FirebaseFunctions) {
12 | return functions;
13 | }
14 | }
15 |
16 | export const FUNCTIONS_PROVIDER_NAME = 'functions';
17 |
18 | // eslint-disable-next-line @typescript-eslint/no-empty-interface
19 | export interface FunctionsInstances extends Array {}
20 |
21 | export class FunctionsInstances {
22 | constructor() {
23 | return ɵgetAllInstancesOf(FUNCTIONS_PROVIDER_NAME);
24 | }
25 | }
26 |
27 | export const functionInstance$ = timer(0, 300).pipe(
28 | concatMap(() => from(ɵgetAllInstancesOf(FUNCTIONS_PROVIDER_NAME))),
29 | distinct(),
30 | );
31 |
--------------------------------------------------------------------------------
/src/functions/ng-package.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "../../node_modules/ng-packagr/ng-package.schema.json",
3 | "lib": {
4 | "entryFile": "public_api.ts"
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/src/functions/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "../../node_modules/ng-packagr/package.schema.json"
3 | }
4 |
--------------------------------------------------------------------------------
/src/functions/public_api.ts:
--------------------------------------------------------------------------------
1 | export { provideFunctions, FunctionsModule } from './functions.module';
2 | export { Functions, FunctionsInstances, functionInstance$ } from './functions';
3 | export * from './rxfire';
4 | export * from './firebase';
5 |
--------------------------------------------------------------------------------
/src/functions/rxfire.ts:
--------------------------------------------------------------------------------
1 | // DO NOT MODIFY, this file is autogenerated by tools/build.ts
2 | import { ɵzoneWrap } from '@angular/fire';
3 | import {
4 | httpsCallable as _httpsCallable
5 | } from 'rxfire/functions';
6 |
7 | export const httpsCallableData = ɵzoneWrap(_httpsCallable, true);
8 |
--------------------------------------------------------------------------------
/src/messaging/firebase.ts:
--------------------------------------------------------------------------------
1 | // DO NOT MODIFY, this file is autogenerated by tools/build.ts
2 | export * from 'firebase/messaging';
3 | import { ɵzoneWrap } from '@angular/fire';
4 | import {
5 | deleteToken as _deleteToken,
6 | getMessaging as _getMessaging,
7 | getToken as _getToken,
8 | isSupported as _isSupported,
9 | onMessage as _onMessage
10 | } from 'firebase/messaging';
11 |
12 | export const deleteToken = ɵzoneWrap(_deleteToken, true, 2);
13 | export const getMessaging = ɵzoneWrap(_getMessaging, true);
14 | export const getToken = ɵzoneWrap(_getToken, true);
15 | export const isSupported = ɵzoneWrap(_isSupported, false);
16 | export const onMessage = ɵzoneWrap(_onMessage, false);
17 |
--------------------------------------------------------------------------------
/src/messaging/messaging.spec.ts:
--------------------------------------------------------------------------------
1 | import { TestBed } from '@angular/core/testing';
2 | import { getApp, initializeApp, provideFirebaseApp } from '@angular/fire/app';
3 | import { Messaging, getMessaging, isSupported, provideMessaging } from '@angular/fire/messaging';
4 | import { COMMON_CONFIG } from '../test-config';
5 | import { rando } from '../utils';
6 |
7 | describe('Messaging', () => {
8 | let messaging: Messaging;
9 | let providedMessaging: Messaging;
10 | let appName: string;
11 |
12 | describe('single injection', () => {
13 |
14 | beforeEach(() => {
15 | appName = rando();
16 | TestBed.configureTestingModule({
17 | providers: [
18 | provideFirebaseApp(() => initializeApp(COMMON_CONFIG, appName)),
19 | provideMessaging(() => {
20 | providedMessaging = getMessaging(getApp(appName));
21 | return providedMessaging;
22 | }),
23 | ],
24 | });
25 | messaging = TestBed.inject(Messaging);
26 | });
27 |
28 | it('should be injectable', async () => {
29 | const supported = await TestBed.runInInjectionContext(isSupported);
30 | if (supported) {
31 | expect(providedMessaging).toBeTruthy();
32 | expect(messaging).toEqual(providedMessaging);
33 | } else {
34 | expect(providedMessaging).toBeUndefined();
35 | expect(messaging).toBeNull();
36 | }
37 | });
38 |
39 | });
40 |
41 | });
42 |
--------------------------------------------------------------------------------
/src/messaging/messaging.ts:
--------------------------------------------------------------------------------
1 | import { ɵgetAllInstancesOf } from '@angular/fire';
2 | import { Messaging as FirebaseMessaging } from 'firebase/messaging';
3 | import { from, timer } from 'rxjs';
4 | import { concatMap, distinct } from 'rxjs/operators';
5 |
6 | // see notes in core/firebase.app.module.ts for why we're building the class like this
7 | // eslint-disable-next-line @typescript-eslint/no-empty-interface
8 | export interface Messaging extends FirebaseMessaging {}
9 |
10 | export class Messaging {
11 | constructor(messaging: FirebaseMessaging) {
12 | return messaging;
13 | }
14 | }
15 |
16 | export const MESSAGING_PROVIDER_NAME = 'messaging';
17 |
18 | // eslint-disable-next-line @typescript-eslint/no-empty-interface
19 | export interface MessagingInstances extends Array {}
20 |
21 | export class MessagingInstances {
22 | constructor() {
23 | return ɵgetAllInstancesOf(MESSAGING_PROVIDER_NAME);
24 | }
25 | }
26 |
27 | export const messagingInstance$ = timer(0, 300).pipe(
28 | concatMap(() => from(ɵgetAllInstancesOf(MESSAGING_PROVIDER_NAME))),
29 | distinct(),
30 | );
31 |
--------------------------------------------------------------------------------
/src/messaging/ng-package.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "../../node_modules/ng-packagr/ng-package.schema.json",
3 | "lib": {
4 | "entryFile": "public_api.ts"
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/src/messaging/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "../../node_modules/ng-packagr/package.schema.json"
3 | }
4 |
--------------------------------------------------------------------------------
/src/messaging/public_api.ts:
--------------------------------------------------------------------------------
1 | export { MessagingInstances, Messaging, messagingInstance$ } from './messaging';
2 | export { provideMessaging, MessagingModule } from './messaging.module';
3 | export * from './firebase';
4 |
--------------------------------------------------------------------------------
/src/ng-package.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "./node_modules/ng-packagr/ng-package.schema.json",
3 | "lib": {
4 | "entryFile": "public_api.ts"
5 | },
6 | "dest": "../dist/packages-dist",
7 | "allowedNonPeerDependencies": [
8 | "@angular-devkit/schematics", "@schematics/angular",
9 | "fuzzy", "inquirer-autocomplete-prompt",
10 | "open", "jsonc-parser", "ora", "winston",
11 | "triple-beam", "@schematics/angular", "node-fetch",
12 | "semver", "inquirer", "fs-extra",
13 | "firebase", "rxfire"
14 | ]
15 | }
16 |
--------------------------------------------------------------------------------
/src/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "../node_modules/ng-packagr/package.schema.json",
3 | "name": "@angular/fire",
4 | "version": "ANGULARFIRE2_VERSION",
5 | "description": "Angular + Firebase = ❤️",
6 | "schematics": "./schematics/collection.json",
7 | "builders": "./schematics/builders.json",
8 | "keywords": [
9 | "angular",
10 | "firebase",
11 | "rxjs",
12 | "angularfire",
13 | "angularfire2"
14 | ],
15 | "repository": {
16 | "type": "git",
17 | "url": "git+https://github.com/angular/angularfire.git"
18 | },
19 | "bugs": {
20 | "url": "https://github.com/angular/angularfire/issues"
21 | },
22 | "homepage": "https://github.com/angular/angularfire#readme",
23 | "author": "angular,firebase",
24 | "license": "MIT",
25 | "peerDependencies": {
26 | "@angular/common": "^20.0.0",
27 | "@angular/core": "^20.0.0",
28 | "@angular/platform-browser": "^20.0.0",
29 | "@angular/platform-browser-dynamic": "^20.0.0",
30 | "@angular/platform-server": "^20.0.0",
31 | "rxjs": "~7.8.0",
32 | "firebase-tools": "^14.0.0"
33 | },
34 | "peerDependenciesMeta": {
35 | "firebase-tools": { "optional": true },
36 | "@angular/platform-server": { "optional": true }
37 | },
38 | "dependencies": {
39 | "firebase": "^11.8.0",
40 | "rxfire": "^6.1.0",
41 | "@angular-devkit/schematics": "^20.0.0",
42 | "@schematics/angular": "^20.0.0",
43 | "tslib": "^2.3.0"
44 | },
45 | "ng-update": {
46 | "migrations": "./schematics/migration.json"
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/src/performance/firebase.ts:
--------------------------------------------------------------------------------
1 | // DO NOT MODIFY, this file is autogenerated by tools/build.ts
2 | export * from 'firebase/performance';
3 | import { ɵzoneWrap } from '@angular/fire';
4 | import {
5 | getPerformance as _getPerformance,
6 | initializePerformance as _initializePerformance,
7 | trace as _trace
8 | } from 'firebase/performance';
9 |
10 | export const getPerformance = ɵzoneWrap(_getPerformance, true);
11 | export const initializePerformance = ɵzoneWrap(_initializePerformance, true);
12 | export const trace = ɵzoneWrap(_trace, true, 2);
13 |
--------------------------------------------------------------------------------
/src/performance/ng-package.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "../../node_modules/ng-packagr/ng-package.schema.json",
3 | "lib": {
4 | "entryFile": "public_api.ts"
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/src/performance/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "../../node_modules/ng-packagr/package.schema.json"
3 | }
4 |
--------------------------------------------------------------------------------
/src/performance/performance.spec.ts:
--------------------------------------------------------------------------------
1 | import { TestBed } from '@angular/core/testing';
2 | import { FirebaseApp, initializeApp, provideFirebaseApp } from '@angular/fire/app';
3 | import { Performance, getPerformance, providePerformance } from '@angular/fire/performance';
4 | import { COMMON_CONFIG } from '../test-config';
5 |
6 | describe('Performance', () => {
7 | let app: FirebaseApp;
8 | let performance: Performance;
9 | let providedPerformance: Performance;
10 |
11 | describe('single injection', () => {
12 |
13 | beforeEach(() => {
14 | TestBed.configureTestingModule({
15 | providers: [
16 | provideFirebaseApp(() => initializeApp(COMMON_CONFIG)),
17 | providePerformance(() => {
18 | providedPerformance = getPerformance();
19 | return providedPerformance;
20 | }),
21 | ],
22 | });
23 | app = TestBed.inject(FirebaseApp);
24 | performance = TestBed.inject(Performance);
25 | });
26 |
27 | it('should be injectable', () => {
28 | expect(providedPerformance).toBeTruthy();
29 | expect(performance).toEqual(providedPerformance);
30 | expect(performance.app).toEqual(app);
31 | });
32 |
33 | });
34 |
35 | });
36 |
--------------------------------------------------------------------------------
/src/performance/performance.ts:
--------------------------------------------------------------------------------
1 | import { ɵgetAllInstancesOf } from '@angular/fire';
2 | import { FirebasePerformance } from 'firebase/performance';
3 | import { from, timer } from 'rxjs';
4 | import { concatMap, distinct } from 'rxjs/operators';
5 |
6 | // see notes in core/firebase.app.module.ts for why we're building the class like this
7 | // eslint-disable-next-line @typescript-eslint/no-empty-interface
8 | export interface Performance extends FirebasePerformance {}
9 |
10 | export class Performance {
11 | constructor(performance: FirebasePerformance) {
12 | return performance;
13 | }
14 | }
15 |
16 | export const PERFORMANCE_PROVIDER_NAME = 'performance';
17 |
18 | // eslint-disable-next-line @typescript-eslint/no-empty-interface
19 | export interface PerformanceInstances extends Array {}
20 |
21 | export class PerformanceInstances {
22 | constructor() {
23 | return ɵgetAllInstancesOf(PERFORMANCE_PROVIDER_NAME);
24 | }
25 | }
26 |
27 | export const performanceInstance$ = timer(0, 300).pipe(
28 | concatMap(() => from(ɵgetAllInstancesOf(PERFORMANCE_PROVIDER_NAME))),
29 | distinct(),
30 | );
31 |
--------------------------------------------------------------------------------
/src/performance/public_api.ts:
--------------------------------------------------------------------------------
1 | export { Performance, PerformanceInstances, performanceInstance$ } from './performance';
2 | export { providePerformance, PerformanceModule } from './performance.module';
3 | export * from './rxfire';
4 | export * from './firebase';
5 |
--------------------------------------------------------------------------------
/src/performance/rxfire.ts:
--------------------------------------------------------------------------------
1 | // DO NOT MODIFY, this file is autogenerated by tools/build.ts
2 | import { ɵzoneWrap } from '@angular/fire';
3 | import {
4 | traceUntil as _traceUntil,
5 | traceUntilComplete as _traceUntilComplete,
6 | traceUntilFirst as _traceUntilFirst,
7 | traceWhile as _traceWhile
8 | } from 'rxfire/performance';
9 |
10 | export const traceUntil = ɵzoneWrap(_traceUntil, true);
11 | export const traceUntilComplete = ɵzoneWrap(_traceUntilComplete, true);
12 | export const traceUntilFirst = ɵzoneWrap(_traceUntilFirst, true);
13 | export const traceWhile = ɵzoneWrap(_traceWhile, true);
14 |
--------------------------------------------------------------------------------
/src/public_api.ts:
--------------------------------------------------------------------------------
1 | export * from './core';
2 | export * from './zones';
3 |
--------------------------------------------------------------------------------
/src/remote-config/firebase.ts:
--------------------------------------------------------------------------------
1 | // DO NOT MODIFY, this file is autogenerated by tools/build.ts
2 | export * from 'firebase/remote-config';
3 | import { ɵzoneWrap } from '@angular/fire';
4 | import {
5 | activate as _activate,
6 | ensureInitialized as _ensureInitialized,
7 | fetchAndActivate as _fetchAndActivate,
8 | fetchConfig as _fetchConfig,
9 | getAll as _getAll,
10 | getBoolean as _getBoolean,
11 | getNumber as _getNumber,
12 | getRemoteConfig as _getRemoteConfig,
13 | getString as _getString,
14 | getValue as _getValue,
15 | isSupported as _isSupported,
16 | setCustomSignals as _setCustomSignals,
17 | setLogLevel as _setLogLevel
18 | } from 'firebase/remote-config';
19 |
20 | export const activate = ɵzoneWrap(_activate, true);
21 | export const ensureInitialized = ɵzoneWrap(_ensureInitialized, true);
22 | export const fetchAndActivate = ɵzoneWrap(_fetchAndActivate, true);
23 | export const fetchConfig = ɵzoneWrap(_fetchConfig, true);
24 | export const getAll = ɵzoneWrap(_getAll, true);
25 | export const getBoolean = ɵzoneWrap(_getBoolean, true);
26 | export const getNumber = ɵzoneWrap(_getNumber, true);
27 | export const getRemoteConfig = ɵzoneWrap(_getRemoteConfig, true);
28 | export const getString = ɵzoneWrap(_getString, true);
29 | export const getValue = ɵzoneWrap(_getValue, true);
30 | export const isSupported = ɵzoneWrap(_isSupported, true);
31 | export const setCustomSignals = ɵzoneWrap(_setCustomSignals, true);
32 | export const setLogLevel = ɵzoneWrap(_setLogLevel, true);
33 |
--------------------------------------------------------------------------------
/src/remote-config/ng-package.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "../../node_modules/ng-packagr/ng-package.schema.json",
3 | "lib": {
4 | "entryFile": "public_api.ts"
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/src/remote-config/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "../../node_modules/ng-packagr/package.schema.json"
3 | }
4 |
--------------------------------------------------------------------------------
/src/remote-config/public_api.ts:
--------------------------------------------------------------------------------
1 | export { RemoteConfigInstances, RemoteConfig, remoteConfigInstance$ } from './remote-config';
2 | export { provideRemoteConfig, RemoteConfigModule } from './remote-config.module';
3 | export * from './rxfire';
4 | export * from './firebase';
5 |
--------------------------------------------------------------------------------
/src/remote-config/remote-config.spec.ts:
--------------------------------------------------------------------------------
1 | import { TestBed } from '@angular/core/testing';
2 | import { FirebaseApp, getApp, initializeApp, provideFirebaseApp } from '@angular/fire/app';
3 | import { RemoteConfig, getRemoteConfig, provideRemoteConfig } from '@angular/fire/remote-config';
4 | import { COMMON_CONFIG } from '../test-config';
5 | import { rando } from '../utils';
6 |
7 | describe('RemoteConfig', () => {
8 | let app: FirebaseApp;
9 | let remoteConfig: RemoteConfig;
10 | let providedRemoteConfig: RemoteConfig;
11 | let appName: string;
12 |
13 | describe('single injection', () => {
14 |
15 | beforeEach(() => {
16 | appName = rando();
17 | TestBed.configureTestingModule({
18 | providers: [
19 | provideFirebaseApp(() => initializeApp(COMMON_CONFIG, appName)),
20 | provideRemoteConfig(() => {
21 | providedRemoteConfig = getRemoteConfig(getApp(appName));
22 | return providedRemoteConfig;
23 | }),
24 | ],
25 | });
26 | app = TestBed.inject(FirebaseApp);
27 | remoteConfig = TestBed.inject(RemoteConfig);
28 | });
29 |
30 | it('should be injectable', () => {
31 | expect(providedRemoteConfig).toBeTruthy();
32 | expect(remoteConfig).toEqual(providedRemoteConfig);
33 | expect(remoteConfig.app).toEqual(app);
34 | });
35 |
36 | });
37 |
38 | });
39 |
--------------------------------------------------------------------------------
/src/remote-config/remote-config.ts:
--------------------------------------------------------------------------------
1 | import { ɵgetAllInstancesOf } from '@angular/fire';
2 | import { RemoteConfig as FirebaseRemoteConfig } from 'firebase/remote-config';
3 | import { from, timer } from 'rxjs';
4 | import { concatMap, distinct } from 'rxjs/operators';
5 |
6 | // see notes in core/firebase.app.module.ts for why we're building the class like this
7 | // eslint-disable-next-line @typescript-eslint/no-empty-interface
8 | export interface RemoteConfig extends FirebaseRemoteConfig {}
9 |
10 | export class RemoteConfig {
11 | constructor(remoteConfig: FirebaseRemoteConfig) {
12 | return remoteConfig;
13 | }
14 | }
15 |
16 | export const REMOTE_CONFIG_PROVIDER_NAME = 'remote-config';
17 |
18 | // eslint-disable-next-line @typescript-eslint/no-empty-interface
19 | export interface RemoteConfigInstances extends Array {}
20 |
21 | export class RemoteConfigInstances {
22 | constructor() {
23 | return ɵgetAllInstancesOf(REMOTE_CONFIG_PROVIDER_NAME);
24 | }
25 | }
26 |
27 | export const remoteConfigInstance$ = timer(0, 300).pipe(
28 | concatMap(() => from(ɵgetAllInstancesOf(REMOTE_CONFIG_PROVIDER_NAME))),
29 | distinct(),
30 | );
31 |
--------------------------------------------------------------------------------
/src/remote-config/rxfire.ts:
--------------------------------------------------------------------------------
1 | // DO NOT MODIFY, this file is autogenerated by tools/build.ts
2 | import { ɵzoneWrap } from '@angular/fire';
3 | import {
4 | getAll as _getAll,
5 | getBoolean as _getBoolean,
6 | getNumber as _getNumber,
7 | getString as _getString,
8 | getValue as _getValue
9 | } from 'rxfire/remote-config';
10 |
11 | export const getAllChanges = ɵzoneWrap(_getAll, true);
12 | export const getBooleanChanges = ɵzoneWrap(_getBoolean, true);
13 | export const getNumberChanges = ɵzoneWrap(_getNumber, true);
14 | export const getStringChanges = ɵzoneWrap(_getString, true);
15 | export const getValueChanges = ɵzoneWrap(_getValue, true);
16 |
--------------------------------------------------------------------------------
/src/schematics/add/index.ts:
--------------------------------------------------------------------------------
1 | import { SchematicContext, Tree } from '@angular-devkit/schematics';
2 | import { NodePackageInstallTask, RunSchematicTask } from '@angular-devkit/schematics/tasks';
3 | import { addDependencies } from '../common';
4 | import { DeployOptions } from '../interfaces';
5 | import { peerDependencies } from '../versions.json';
6 |
7 | export const ngAdd = (options: DeployOptions) => (tree: Tree, context: SchematicContext) => {
8 | addDependencies(
9 | tree,
10 | peerDependencies,
11 | context
12 | );
13 | const npmInstallTaskId = context.addTask(new NodePackageInstallTask());
14 | context.addTask(new RunSchematicTask('ng-add-setup-project', options), [npmInstallTaskId]);
15 | return tree;
16 | };
17 |
--------------------------------------------------------------------------------
/src/schematics/add/schema.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "http://json-schema.org/draft-07/schema",
3 | "$id": "angular-fire-ng-add",
4 | "title": "AngularFire ng-add",
5 | "type": "object",
6 | "properties": {
7 | "project": {
8 | "type": "string",
9 | "description": "The name of the project.",
10 | "$default": {
11 | "$source": "projectName"
12 | }
13 | }
14 | },
15 | "required": []
16 | }
17 |
--------------------------------------------------------------------------------
/src/schematics/builders.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "../../node_modules/@angular-devkit/schematics/collection-schema.json",
3 | "builders": {
4 | "deploy": {
5 | "implementation": "./deploy/builder",
6 | "schema": "./deploy/schema.json",
7 | "description": "Deploy builder"
8 | }
9 | }
10 | }
--------------------------------------------------------------------------------
/src/schematics/collection.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "../../node_modules/@angular-devkit/schematics/collection-schema.json",
3 | "schematics": {
4 | "ng-add": {
5 | "description": "Add firebase deploy schematic",
6 | "factory": "./add#ngAdd",
7 | "schema": "./add/schema.json"
8 | },
9 | "ng-add-setup-project": {
10 | "description": "Setup ng deploy",
11 | "factory": "./setup#ngAddSetupProject",
12 | "schema": "./setup/schema.json"
13 | }
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/src/schematics/migration.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "../../node_modules/@angular-devkit/schematics/collection-schema.json",
3 | "schematics": {
4 | "migration-v7": {
5 | "version": "7.0.0",
6 | "description": "Update @angular/fire to v7",
7 | "factory": "./update/v7#ngUpdate"
8 | },
9 | "ng-post-upgate": {
10 | "description": "Print out results after ng-update",
11 | "factory": "./update#ngPostUpdate",
12 | "private": true
13 | }
14 | }
15 | }
--------------------------------------------------------------------------------
/src/schematics/setup/schema.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "http://json-schema.org/draft-07/schema",
3 | "$id": "angular-fire-ng-add",
4 | "title": "AngularFire ng-add",
5 | "type": "object",
6 | "properties": {
7 | "project": {
8 | "type": "string",
9 | "description": "The name of the project.",
10 | "$default": {
11 | "$source": "projectName"
12 | }
13 | }
14 | },
15 | "required": []
16 | }
17 |
--------------------------------------------------------------------------------
/src/schematics/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "rootDir": ".",
4 | "sourceMap": false,
5 | "inlineSources": false,
6 | "declaration": false,
7 | "removeComments": true,
8 | "strictNullChecks": true,
9 | "resolveJsonModule": true,
10 | "esModuleInterop": true,
11 | "lib": [
12 | "es2015",
13 | "dom",
14 | "es2015.promise",
15 | "es2015.collection",
16 | "es2015.iterable"
17 | ],
18 | "skipLibCheck": true,
19 | "moduleResolution": "node",
20 | "target": "es2018",
21 | "module": "commonjs",
22 | "outDir": "../../dist/packages-dist/schematics"
23 | },
24 | "files": [
25 | "update/index.ts",
26 | "deploy/actions.ts",
27 | "deploy/builder.ts",
28 | "add/index.ts",
29 | "setup/index.ts",
30 | "update/v7/index.ts",
31 | ]
32 | }
--------------------------------------------------------------------------------
/src/schematics/update/index.ts:
--------------------------------------------------------------------------------
1 | import { Rule, SchematicContext, Tree } from '@angular-devkit/schematics';
2 |
3 | export const ngPostUpdate = (): Rule => (
4 | host: Tree,
5 | _context: SchematicContext
6 | ) => {
7 | return host;
8 | };
9 |
--------------------------------------------------------------------------------
/src/schematics/versions.json:
--------------------------------------------------------------------------------
1 | {
2 | "peerDependencies": {
3 | },
4 | "firebaseFunctionsDependencies": {
5 | "firebase-admin": { "dev": false, "version": "0.0.0" },
6 | "firebase-functions": { "dev": false, "version": "0.0.0" }
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/src/storage/firebase.ts:
--------------------------------------------------------------------------------
1 | // DO NOT MODIFY, this file is autogenerated by tools/build.ts
2 | export * from 'firebase/storage';
3 | import { ɵzoneWrap } from '@angular/fire';
4 | import {
5 | connectStorageEmulator as _connectStorageEmulator,
6 | deleteObject as _deleteObject,
7 | getBlob as _getBlob,
8 | getBytes as _getBytes,
9 | getDownloadURL as _getDownloadURL,
10 | getMetadata as _getMetadata,
11 | getStorage as _getStorage,
12 | getStream as _getStream,
13 | list as _list,
14 | listAll as _listAll,
15 | ref as _ref,
16 | updateMetadata as _updateMetadata,
17 | uploadBytes as _uploadBytes,
18 | uploadBytesResumable as _uploadBytesResumable,
19 | uploadString as _uploadString
20 | } from 'firebase/storage';
21 |
22 | export const connectStorageEmulator = ɵzoneWrap(_connectStorageEmulator, true);
23 | export const deleteObject = ɵzoneWrap(_deleteObject, true, 2);
24 | export const getBlob = ɵzoneWrap(_getBlob, true);
25 | export const getBytes = ɵzoneWrap(_getBytes, true);
26 | export const getDownloadURL = ɵzoneWrap(_getDownloadURL, true);
27 | export const getMetadata = ɵzoneWrap(_getMetadata, true);
28 | export const getStorage = ɵzoneWrap(_getStorage, true);
29 | export const getStream = ɵzoneWrap(_getStream, true);
30 | export const list = ɵzoneWrap(_list, true);
31 | export const listAll = ɵzoneWrap(_listAll, true);
32 | export const ref = ɵzoneWrap(_ref, true, 2);
33 | export const updateMetadata = ɵzoneWrap(_updateMetadata, true, 2);
34 | export const uploadBytes = ɵzoneWrap(_uploadBytes, true);
35 | export const uploadBytesResumable = ɵzoneWrap(_uploadBytesResumable, true);
36 | export const uploadString = ɵzoneWrap(_uploadString, true);
37 |
--------------------------------------------------------------------------------
/src/storage/ng-package.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "../../node_modules/ng-packagr/ng-package.schema.json",
3 | "lib": {
4 | "entryFile": "public_api.ts"
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/src/storage/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "../../node_modules/ng-packagr/package.schema.json"
3 | }
4 |
--------------------------------------------------------------------------------
/src/storage/public_api.ts:
--------------------------------------------------------------------------------
1 | export { Storage, StorageInstances, storageInstance$ } from './storage';
2 | export { provideStorage, StorageModule } from './storage.module';
3 | export * from './rxfire';
4 | export * from './firebase';
5 |
--------------------------------------------------------------------------------
/src/storage/rxfire.ts:
--------------------------------------------------------------------------------
1 | // DO NOT MODIFY, this file is autogenerated by tools/build.ts
2 | import { ɵzoneWrap } from '@angular/fire';
3 | import {
4 | fromTask as _fromTask,
5 | percentage as _percentage
6 | } from 'rxfire/storage';
7 |
8 | export const fromTask = ɵzoneWrap(_fromTask, true);
9 | export const percentage = ɵzoneWrap(_percentage, true);
10 |
--------------------------------------------------------------------------------
/src/storage/storage.spec.ts:
--------------------------------------------------------------------------------
1 | import { TestBed } from '@angular/core/testing';
2 | import { FirebaseApp, getApp, initializeApp, provideFirebaseApp } from '@angular/fire/app';
3 | import { Storage, connectStorageEmulator, getStorage, provideStorage } from '@angular/fire/storage';
4 | import { COMMON_CONFIG } from '../test-config';
5 | import { rando } from '../utils';
6 |
7 | describe('Storage', () => {
8 | let app: FirebaseApp;
9 | let storage: Storage;
10 | let providedStorage: Storage;
11 | let appName: string;
12 |
13 | describe('single injection', () => {
14 |
15 | beforeEach(() => {
16 | appName = rando();
17 | TestBed.configureTestingModule({
18 | providers: [
19 | provideFirebaseApp(() => initializeApp(COMMON_CONFIG, appName)),
20 | provideStorage(() => {
21 | providedStorage = getStorage(getApp(appName));
22 | connectStorageEmulator(providedStorage, 'localhost', 9199);
23 | return providedStorage;
24 | }),
25 | ],
26 | });
27 | app = TestBed.inject(FirebaseApp);
28 | storage = TestBed.inject(Storage);
29 | });
30 |
31 | it('should be injectable', () => {
32 | expect(providedStorage).toBeTruthy();
33 | expect(storage).toEqual(providedStorage);
34 | expect(storage.app).toEqual(app);
35 | });
36 |
37 | });
38 |
39 | });
40 |
--------------------------------------------------------------------------------
/src/storage/storage.ts:
--------------------------------------------------------------------------------
1 | import { ɵgetAllInstancesOf } from '@angular/fire';
2 | import { FirebaseStorage } from 'firebase/storage';
3 | import { from, timer } from 'rxjs';
4 | import { concatMap, distinct } from 'rxjs/operators';
5 |
6 | // see notes in core/firebase.app.module.ts for why we're building the class like this
7 | // eslint-disable-next-line @typescript-eslint/no-empty-interface
8 | export interface Storage extends FirebaseStorage {}
9 |
10 | export class Storage {
11 | constructor(auth: FirebaseStorage) {
12 | return auth;
13 | }
14 | }
15 |
16 | export const STORAGE_PROVIDER_NAME = 'storage';
17 |
18 | // eslint-disable-next-line @typescript-eslint/no-empty-interface
19 | export interface StorageInstances extends Array {}
20 |
21 | export class StorageInstances {
22 | constructor() {
23 | return ɵgetAllInstancesOf(STORAGE_PROVIDER_NAME);
24 | }
25 | }
26 |
27 | export const storageInstance$ = timer(0, 300).pipe(
28 | concatMap(() => from(ɵgetAllInstancesOf(STORAGE_PROVIDER_NAME))),
29 | distinct(),
30 | );
31 |
--------------------------------------------------------------------------------
/src/test-config.ts:
--------------------------------------------------------------------------------
1 | export const COMMON_CONFIG = {
2 | apiKey: 'AIzaSyBVSy3YpkVGiKXbbxeK0qBnu3-MNZ9UIjA',
3 | authDomain: 'angularfire2-test.firebaseapp.com',
4 | databaseURL: 'https://angularfire2-test.firebaseio.com',
5 | projectId: 'angularfire2-test',
6 | storageBucket: 'angularfire2-test.appspot.com',
7 | messagingSenderId: '920323787688',
8 | appId: '1:920323787688:web:2253a0e5eb5b9a8b',
9 | databaseName: 'angularfire2-test',
10 | measurementId: 'G-W20QDV5CZP'
11 | };
12 |
13 | export const COMMON_CONFIG_TOO = {
14 | apiKey: 'AIzaSyBVSy3YpkVGiKXbbxeK0qBnu3-MNZ9UIjA',
15 | authDomain: 'angularfire2-test.firebaseapp.com',
16 | databaseURL: 'https://angularfire2-test.firebaseio.com',
17 | projectId: 'angularfire2-test',
18 | storageBucket: 'angularfire2-test.appspot.com',
19 | messagingSenderId: '920323787688',
20 | appId: '1:920323787688:web:2253a0e5eb5b9a8d',
21 | databaseName: 'angularfire2-test',
22 | measurementId: 'G-W20QDV5CZZ'
23 | };
24 |
25 | declare global {
26 | interface Window {
27 | __karma__ : {
28 | config: {
29 | args: any[]
30 | }
31 | };
32 | }
33 | }
34 |
35 | export const firestoreEmulatorPort: number = window.__karma__.config.args.find((it) => it[0] === "FIRESTORE_EMULATOR_PORT")[1];
36 | export const storageEmulatorPort: number = window.__karma__.config.args.find((it) => it[0] === "STORAGE_EMULATOR_PORT")[1];
37 | export const authEmulatorPort: number = window.__karma__.config.args.find((it) => it[0] === "AUTH_EMULATOR_PORT")[1];
38 | export const databaseEmulatorPort: number = window.__karma__.config.args.find((it) => it[0] === "DATABASE_EMULATOR_PORT")[1];
39 | export const functionsEmulatorPort: number = window.__karma__.config.args.find((it) => it[0] === "FUNCTIONS_EMULATOR_PORT")[1];
40 |
--------------------------------------------------------------------------------
/src/test.ts:
--------------------------------------------------------------------------------
1 | // This file is required by karma.conf.js and loads recursively all the .spec and framework files
2 |
3 | import 'zone.js/dist/zone';
4 | import 'zone.js/dist/zone-testing';
5 | import 'zone.js/dist/task-tracking';
6 |
7 | import { getTestBed } from '@angular/core/testing';
8 | import { BrowserDynamicTestingModule, platformBrowserDynamicTesting } from '@angular/platform-browser-dynamic/testing';
9 |
10 | declare const require: any;
11 |
12 | // First, initialize the Angular testing environment.
13 | getTestBed().initTestEnvironment(
14 | BrowserDynamicTestingModule,
15 | platformBrowserDynamicTesting()
16 | );
17 | // Then we find all the tests.
18 | const context = require.context('./', true, /^\.\/.+\.spec\.ts$/);
19 |
20 | // And load the modules.
21 | context.keys().map(context);
22 |
--------------------------------------------------------------------------------
/src/utils.ts:
--------------------------------------------------------------------------------
1 | const randomString = () => (Math.random() + 1).toString(36).split('.')[1];
2 |
3 | export const rando = () => [randomString(), randomString(), randomString()].join('');
4 |
--------------------------------------------------------------------------------
/src/vertexai/firebase.ts:
--------------------------------------------------------------------------------
1 | // DO NOT MODIFY, this file is autogenerated by tools/build.ts
2 | export * from 'firebase/vertexai';
3 | import { ɵzoneWrap } from '@angular/fire';
4 | import {
5 | getAI as _getAI,
6 | getGenerativeModel as _getGenerativeModel,
7 | getImagenModel as _getImagenModel,
8 | getVertexAI as _getVertexAI
9 | } from 'firebase/vertexai';
10 |
11 | export const getAI = ɵzoneWrap(_getAI, true);
12 | export const getGenerativeModel = ɵzoneWrap(_getGenerativeModel, true);
13 | export const getImagenModel = ɵzoneWrap(_getImagenModel, true);
14 | export const getVertexAI = ɵzoneWrap(_getVertexAI, true);
15 |
--------------------------------------------------------------------------------
/src/vertexai/ng-package.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "../../node_modules/ng-packagr/ng-package.schema.json",
3 | "lib": {
4 | "entryFile": "public_api.ts"
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/src/vertexai/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "../../node_modules/ng-packagr/package.schema.json"
3 | }
4 |
--------------------------------------------------------------------------------
/src/vertexai/public_api.ts:
--------------------------------------------------------------------------------
1 | export { VertexAI, VertexAIInstances, vertexAIInstance$ } from './vertexai';
2 | export { provideVertexAI, VertexAIModule } from './vertexai.module';
3 | export * from './firebase';
4 |
--------------------------------------------------------------------------------
/src/vertexai/vertexai.spec.ts:
--------------------------------------------------------------------------------
1 | import { TestBed } from '@angular/core/testing';
2 | import { FirebaseApp, getApp, initializeApp, provideFirebaseApp } from '@angular/fire/app';
3 | import { VertexAI, getVertexAI, provideVertexAI } from '@angular/fire/vertexai';
4 | import { COMMON_CONFIG } from '../test-config';
5 | import { rando } from '../utils';
6 |
7 | describe('VertexAI', () => {
8 | let app: FirebaseApp;
9 | let vertexAI: VertexAI;
10 | let providedVertexAI: VertexAI;
11 | let appName: string;
12 |
13 | describe('single injection', () => {
14 |
15 | beforeEach(() => {
16 | appName = rando();
17 | TestBed.configureTestingModule({
18 | providers: [
19 | provideFirebaseApp(() => initializeApp(COMMON_CONFIG, appName)),
20 | provideVertexAI(() => {
21 | providedVertexAI = getVertexAI(getApp(appName));
22 | return providedVertexAI;
23 | }),
24 | ],
25 | });
26 | app = TestBed.inject(FirebaseApp);
27 | vertexAI = TestBed.inject(VertexAI);
28 | });
29 |
30 | it('should be injectable', () => {
31 | expect(providedVertexAI).toBeTruthy();
32 | expect(vertexAI).toEqual(providedVertexAI);
33 | expect(vertexAI.app).toEqual(app);
34 | });
35 |
36 | });
37 |
38 | });
39 |
--------------------------------------------------------------------------------
/src/vertexai/vertexai.ts:
--------------------------------------------------------------------------------
1 | import { ɵgetAllInstancesOf } from '@angular/fire';
2 | import { VertexAI as FirebaseVertexAI } from 'firebase/vertexai';
3 | import { from, timer } from 'rxjs';
4 | import { concatMap, distinct } from 'rxjs/operators';
5 |
6 | // see notes in core/firebase.app.module.ts for why we're building the class like this
7 | // eslint-disable-next-line @typescript-eslint/no-empty-interface
8 | export interface VertexAI extends FirebaseVertexAI {}
9 |
10 | export class VertexAI {
11 | constructor(vertexai: FirebaseVertexAI) {
12 | return vertexai;
13 | }
14 | }
15 |
16 | export const VERTEX_AI_PROVIDER_NAME = 'vertexai';
17 |
18 | // eslint-disable-next-line @typescript-eslint/no-empty-interface
19 | export interface VertexAIInstances extends Array {}
20 |
21 | export class VertexAIInstances {
22 | constructor() {
23 | return ɵgetAllInstancesOf(VERTEX_AI_PROVIDER_NAME);
24 | }
25 | }
26 |
27 | export const vertexAIInstance$ = timer(0, 300).pipe(
28 | concatMap(() => from(ɵgetAllInstancesOf(VERTEX_AI_PROVIDER_NAME))),
29 | distinct(),
30 | );
31 |
--------------------------------------------------------------------------------
/test/database.rules.json:
--------------------------------------------------------------------------------
1 | {
2 | "rules": {
3 | ".read": true,
4 | ".write": true,
5 | ".indexOn": [
6 | "height",
7 | ".value"
8 | ]
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/test/firestore.indexes.json:
--------------------------------------------------------------------------------
1 | {
2 | "indexes": [],
3 | "fieldOverrides": []
4 | }
5 |
--------------------------------------------------------------------------------
/test/firestore.rules:
--------------------------------------------------------------------------------
1 | service cloud.firestore {
2 | match /databases/{database}/documents {
3 | match /{document=**} {
4 | allow read, write: if true;
5 | }
6 | }
7 | }
--------------------------------------------------------------------------------
/test/functions/.gitignore:
--------------------------------------------------------------------------------
1 | # Compiled JavaScript files
2 | lib/**/*.js
3 | lib/**/*.js.map
4 |
5 | # TypeScript v1 declaration files
6 | typings/
7 |
8 | # Node.js dependency directory
9 | node_modules/
10 | *.local
--------------------------------------------------------------------------------
/test/functions/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "functions",
3 | "scripts": {
4 | "build": "tsc",
5 | "build:watch": "tsc --watch",
6 | "serve": "npm run build && firebase emulators:start --only functions",
7 | "shell": "npm run build && firebase functions:shell",
8 | "start": "npm run shell",
9 | "deploy": "firebase deploy --only functions",
10 | "logs": "firebase functions:log"
11 | },
12 | "engines": {
13 | "node": "18"
14 | },
15 | "main": "lib/index.js",
16 | "dependencies": {
17 | "firebase-admin": "^12.6.0",
18 | "firebase-functions": "^6.0.1"
19 | },
20 | "devDependencies": {
21 | "typescript": "^4.9.0",
22 | "firebase-functions-test": "^3.1.0"
23 | },
24 | "private": true
25 | }
--------------------------------------------------------------------------------
/test/functions/src/index.ts:
--------------------------------------------------------------------------------
1 | import { onCall } from "firebase-functions/v2/https";
2 |
3 | export const foo = onCall(() => {
4 | return { bar: "baz" };
5 | });
6 |
--------------------------------------------------------------------------------
/test/functions/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "module": "commonjs",
4 | "noImplicitReturns": true,
5 | "noUnusedLocals": true,
6 | "outDir": "lib",
7 | "sourceMap": true,
8 | "strict": true,
9 | "target": "es2017"
10 | },
11 | "compileOnSave": true,
12 | "include": [
13 | "src"
14 | ]
15 | }
16 |
--------------------------------------------------------------------------------
/test/storage.rules:
--------------------------------------------------------------------------------
1 | rules_version = '2';
2 | service firebase.storage {
3 | match /b/{bucket}/o {
4 | match /{allPaths=**} {
5 | allow read, write: if true;
6 | }
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/tools/build.sh:
--------------------------------------------------------------------------------
1 | SHORT_SHA=$(git rev-parse --short $GITHUB_SHA)
2 | TAG_TEST="^refs/tags/.+$"
3 | LATEST_TEST="^[^-]*$"
4 |
5 | if [[ $GITHUB_REF =~ $TAG_TEST ]]; then
6 | OVERRIDE_VERSION=${GITHUB_REF/refs\/tags\//}
7 | if [[ $OVERRIDE_VERSION =~ $LATEST_TEST ]]; then
8 | NPM_TAG=latest
9 | else
10 | NPM_TAG=next
11 | fi;
12 | else
13 | OVERRIDE_VERSION=$(node -e "console.log(require('./package.json').version)")-canary.$SHORT_SHA
14 | NPM_TAG=canary
15 | fi;
16 |
17 | npm --no-git-tag-version --allow-same-version -f version $OVERRIDE_VERSION
18 |
19 | npm run build &&
20 | echo "npm publish . --tag $NPM_TAG" > ./dist/packages-dist/publish.sh &&
21 | chmod +x ./dist/packages-dist/publish.sh
22 |
--------------------------------------------------------------------------------
/tools/jasmine.ts:
--------------------------------------------------------------------------------
1 | // @ts-ignore
2 | import Jasmine from 'jasmine';
3 |
4 | import 'reflect-metadata';
5 | import 'zone.js';
6 |
7 | import { getTestBed } from '@angular/core/testing';
8 | import { platformServerTesting, ServerTestingModule } from '@angular/platform-server/testing';
9 |
10 | // First, initialize the Angular testing environment.
11 | getTestBed().initTestEnvironment(
12 | ServerTestingModule,
13 | platformServerTesting()
14 | );
15 |
16 | const tests = new Jasmine({});
17 | tests.loadConfig({
18 | spec_dir: '.',
19 | spec_files: [
20 | 'dist/out-tsc/jasmine/**/*.jasmine.js',
21 | 'dist/out-tsc/jasmine/**/*.spec.js',
22 | ]
23 | });
24 |
25 | tests.execute();
26 |
--------------------------------------------------------------------------------
/tsconfig.base.json:
--------------------------------------------------------------------------------
1 | {
2 | "compileOnSave": false,
3 | "compilerOptions": {
4 | "allowSyntheticDefaultImports": true,
5 | "baseUrl": "./",
6 | "outDir": "./dist",
7 | "sourceMap": true,
8 | "declaration": false,
9 | "downlevelIteration": true,
10 | "emitDecoratorMetadata": true,
11 | "experimentalDecorators": true,
12 | "module": "esnext",
13 | "moduleResolution": "node",
14 | "importHelpers": true,
15 | "target": "es2020",
16 | "skipLibCheck": true,
17 | "typeRoots": [
18 | "node_modules/@types"
19 | ],
20 | "lib": [
21 | "es2018",
22 | "dom"
23 | ],
24 | "paths": {
25 | "@angular/fire": ["dist/packages-dist"],
26 | "@angular/fire/*": ["dist/packages-dist/*"]
27 | }
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/tsconfig.build.json:
--------------------------------------------------------------------------------
1 | {
2 | "files": [
3 | "tools/build.ts"
4 | ],
5 | "compilerOptions": {
6 | "outDir": "tools",
7 | "skipLibCheck": true,
8 | "lib": ["es2019", "dom"],
9 | "module": "commonjs",
10 | "target": "ES2020",
11 | "plugins": [
12 | { "transform": "ts-transformer-keys/transformer" }
13 | ],
14 | "baseUrl": "./"
15 | }
16 | }
--------------------------------------------------------------------------------
/tsconfig.jasmine.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "./tsconfig.base.json",
3 | "compilerOptions": {
4 | "outDir": "dist/out-tsc/jasmine",
5 | "module": "commonjs",
6 | "target": "es2015",
7 | "allowJs": true,
8 | "resolveJsonModule": true,
9 | "esModuleInterop": true,
10 | "types": [
11 | "jasmine",
12 | "node"
13 | ]
14 | },
15 | "include": [
16 | "tools/jasmine.ts",
17 | "src/**/*.jasmine.ts",
18 | // Not sure what is wrong here, but since upgrading karma it's fallen apart
19 | // "src/**/*.spec.ts",
20 | "src/**/*.d.ts",
21 | "node_modules/zone.js/zone.d.ts"
22 | ]
23 | }
24 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "./tsconfig.base.json",
3 | "compilerOptions": {
4 | "outDir": "dist/out-tsc/lib",
5 | "target": "es2015",
6 | "declaration": true,
7 | "inlineSources": true,
8 | "declarationMap": false,
9 | "types": [
10 | "node"
11 | ],
12 | "lib": [
13 | "dom",
14 | "es2018"
15 | ]
16 | },
17 | "angularCompilerOptions": {
18 | "compilationMode": "partial"
19 | },
20 | "exclude": [
21 | "src/test.ts",
22 | "src/**/*.spec.ts"
23 | ]
24 | }
25 |
--------------------------------------------------------------------------------
/tsconfig.spec.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "./tsconfig.base.json",
3 | "compilerOptions": {
4 | "outDir": "dist/out-tsc/spec",
5 | "types": [
6 | "jasmine",
7 | "node"
8 | ]
9 | },
10 | "files": [
11 | "src/test.ts"
12 | ],
13 | "include": [
14 | "src/**/*.spec.ts",
15 | "src/**/*.d.ts",
16 | "node_modules/zone.js/zone.d.ts"
17 | ]
18 | }
19 |
--------------------------------------------------------------------------------
/typedoc.json:
--------------------------------------------------------------------------------
1 | {
2 | "tsconfig": "./tsconfig.json",
3 | "ignoreCompilerErrors": true,
4 | "mode": "modules",
5 | "excludeExternals": true,
6 | "excludeNotExported": true,
7 | "excludePrivate": true,
8 | "excludeProtected": true,
9 | "includeDeclarations": true,
10 | "disableOutputCheck": true
11 | }
--------------------------------------------------------------------------------