├── .editorconfig ├── .github ├── FUNDING.yml └── workflows │ └── firebaseui-angular.yml ├── .gitignore ├── .nvmrc ├── CHANGELOG.MD ├── LICENSE ├── README.MD ├── angular.json ├── assets └── LoginScreen.PNG ├── e2e ├── protractor.conf.js ├── src │ ├── app.e2e-spec.ts │ └── app.po.ts └── tsconfig.e2e.json ├── package-lock.json ├── package.json ├── projects └── firebaseui-angular-library │ ├── karma.conf.js │ ├── ng-package.json │ ├── package.json │ ├── src │ ├── lib │ │ ├── firebaseui-angular-library.component.spec.ts │ │ ├── firebaseui-angular-library.component.ts │ │ ├── firebaseui-angular-library.helper.ts │ │ ├── firebaseui-angular-library.module.ts │ │ └── firebaseui-angular-library.service.ts │ ├── public_api.ts │ └── test.ts │ ├── tsconfig.lib.json │ ├── tsconfig.lib.prod.json │ ├── tsconfig.spec.json │ └── tslint.json ├── src ├── .browserslistrc ├── app │ ├── app-routing.module.ts │ ├── app.component.html │ ├── app.component.scss │ ├── app.component.ts │ ├── main │ │ ├── main.component.html │ │ ├── main.component.scss │ │ ├── main.component.ts │ │ └── main.module.ts │ └── second-page │ │ ├── second-page.component.html │ │ ├── second-page.component.scss │ │ ├── second-page.component.ts │ │ └── second.module.ts ├── assets │ └── .gitkeep ├── environments │ ├── environment.prod.ts │ └── environment.ts ├── favicon.ico ├── index.html ├── karma.conf.js ├── main.ts ├── polyfills.ts ├── styles.scss ├── test.ts ├── tsconfig.app.json ├── tsconfig.spec.json └── tslint.json ├── tsconfig.json └── tslint.json /.editorconfig: -------------------------------------------------------------------------------- 1 | # Editor configuration, see http://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 | [*.md] 12 | max_line_length = off 13 | trim_trailing_whitespace = false 14 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2] 4 | patreon: # Replace with a single Patreon username 5 | open_collective: # Replace with a single Open Collective username 6 | ko_fi: # Replace with a single Ko-fi username 7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel 8 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry 9 | liberapay: # Replace with a single Liberapay username 10 | issuehunt: # Replace with a single IssueHunt username 11 | otechie: # Replace with a single Otechie username 12 | custom: ['https://www.buymeacoffee.com/raphaeljenni'] 13 | -------------------------------------------------------------------------------- /.github/workflows/firebaseui-angular.yml: -------------------------------------------------------------------------------- 1 | name: RaphaelJenni/FirebaseUI-Angular 2 | on: 3 | push: 4 | branches: 5 | - 'master' 6 | tags: 7 | - 'v*' 8 | 9 | concurrency: 10 | group: "${{ github.ref }}" 11 | cancel-in-progress: true 12 | 13 | env: 14 | NPM_TOKEN: "${{ secrets.NPM_TOKEN }}" 15 | 16 | jobs: 17 | build-deploy: 18 | runs-on: ubuntu-latest 19 | steps: 20 | - uses: actions/setup-node@v3 21 | with: 22 | node-version: '20' 23 | registry-url: 'https://registry.npmjs.org' 24 | - name: checkout 25 | uses: actions/checkout@v4.1.0 26 | - run: npm ci --legacy-peer-deps 27 | - run: npm run build-lib 28 | - run: npm publish ./dist/firebaseui-angular-library 29 | if: github.ref_type == 'tag' 30 | env: 31 | NODE_AUTH_TOKEN: "${{ secrets.NPM_TOKEN }}" 32 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # See http://help.github.com/ignore-files/ for more about ignoring files. 2 | 3 | # compiled output 4 | /dist 5 | /tmp 6 | /out-tsc 7 | 8 | # dependencies 9 | node_modules/ 10 | 11 | # IDEs and editors 12 | /.idea 13 | .project 14 | .classpath 15 | .c9/ 16 | *.launch 17 | .settings/ 18 | *.sublime-workspace 19 | 20 | # IDE - VSCode 21 | .vscode/* 22 | !.vscode/settings.json 23 | !.vscode/tasks.json 24 | !.vscode/launch.json 25 | !.vscode/extensions.json 26 | 27 | # misc 28 | /.angular/cache 29 | /.sass-cache 30 | /connect.lock 31 | /coverage 32 | /libpeerconnection.log 33 | npm-debug.log 34 | yarn-error.log 35 | testem.log 36 | /typings 37 | 38 | # System Files 39 | .DS_Store 40 | Thumbs.db 41 | -------------------------------------------------------------------------------- /.nvmrc: -------------------------------------------------------------------------------- 1 | v20.10.0 2 | -------------------------------------------------------------------------------- /CHANGELOG.MD: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | # 6.3.0 4 | - Add support for AngularFire 18 [#209](https://github.com/RaphaelJenni/FirebaseUI-Angular/issues/209) 5 | 6 | # 6.2.1 7 | - Add support for AngularFire 17 [#206](https://github.com/RaphaelJenni/FirebaseUI-Angular/pull/206) (Thanks to @garri1105) 8 | 9 | ## 6.2.0 10 | - Update dependencies 11 | - Remove support for legacy versions 12 | 13 | ## 6.1.5 14 | - Add support for Angular 17 [#204](https://github.com/RaphaelJenni/FirebaseUI-Angular/issues/204) 15 | 16 | ## 6.1.4 17 | - Add support for Angular 16 [#199](https://github.com/RaphaelJenni/FirebaseUI-Angular/issues/199) (Thanks to @GeorgeSokolovsky) 18 | 19 | ## 6.1.3 20 | - Add support for Angular 15 [#185](https://github.com/RaphaelJenni/FirebaseUI-Angular/issues/185) 21 | 22 | ## 6.1.2 23 | - Add support for Angular 14 [#179](https://github.com/RaphaelJenni/FirebaseUI-Angular/issues/179) 24 | 25 | ## 6.1.1 26 | - Handle new emulator url correctly [#171](https://github.com/RaphaelJenni/FirebaseUI-Angular/pull/171) (Thanks to @Mikael-Eliasson) 27 | 28 | ## 6.1.0 29 | - Support for Angular 13 30 | 31 | ## 6.0.0 32 | - See 6.0.0-beta.0 - Update to firebaseui@6.0.0 33 | 34 | ## 6.0.0-beta.0 35 | * Compatibility with @angular/fire@^7.0.0 [#158](https://github.com/RaphaelJenni/FirebaseUI-Angular/issues/158) 36 | * FirebaseUI needs to add support for firebase@9 (See [#877](https://github.com/firebase/firebaseui-web/issues/877)). 37 | Use `firebase@next` version (0.600.0) to get support for the compat layer. 38 | * Change from View Engine to Ivy 39 | 40 | ## 5.1.3 41 | * Add support for Angular 12 [#157](https://github.com/RaphaelJenni/FirebaseUI-Angular/issues/157) 42 | 43 | ## 5.1.2 44 | * Add support for Auth Emulator [#142](https://github.com/RaphaelJenni/FirebaseUI-Angular/issues/142) 45 | 46 | ## 5.1.1 47 | * Add support for Angular 11 48 | 49 | ## 5.1.0 50 | * Add support for firebase@^8.0.0 51 | 52 | ## 5.0.1 53 | * Add support for uiShow Callback [#133](https://github.com/RaphaelJenni/FirebaseUI-Angular/issues/133) 54 | 55 | ## 5.0.0 56 | * Upgrade library to support @angular/fire@6.0.0 [#121](https://github.com/RaphaelJenni/FirebaseUI-Angular/issues/121) 57 | 58 | ## 4.1.0 59 | * Update to Angular 9 [#113](https://github.com/RaphaelJenni/FirebaseUI-Angular/issues/92) Thanks to @l0ll098 for the PR 60 | 61 | ## 4.0.0 62 | * Dump old configurations 63 | * Update sample project to Angular 8 64 | * Update peer dependencies configuration 65 | 66 | ## 3.4.2 67 | * Fix service provided always in root instead of AngularFireAuthModule [#92](https://github.com/RaphaelJenni/FirebaseUI-Angular/issues/92) 68 | 69 | ## 3.4.1 70 | * Fix callbacks running outside the angular zone [#85](https://github.com/RaphaelJenni/FirebaseUI-Angular/issues/85) 71 | * Fix bug introduced with 3.4.0 72 | 73 | ## 3.4.0 74 | * Add forFeature module initializer [#57](https://github.com/RaphaelJenni/FirebaseUI-Angular/issues/57) 75 | 76 | ## 3.3.3 77 | * Fix callbacks not getting updated [#81](https://github.com/RaphaelJenni/FirebaseUI-Angular/issues/81) 78 | 79 | ## 3.3.2 80 | * Workaround for --prod build error [#76](https://github.com/RaphaelJenni/FirebaseUI-Angular/issues/76) 81 | 82 | ## 3.3.1 83 | * Fix [#77](https://github.com/RaphaelJenni/FirebaseUI-Angular/issues/77) 84 | * Update dependencies 85 | 86 | ## 3.3.0 87 | * (**IMPORTANT**) Migrate from firebaseui-angular config to firebaseui config 88 | _After updating run your app and you will get the new configuration printed to the console._ 89 | * Update dependencies 90 | * Fix [#73](https://github.com/RaphaelJenni/FirebaseUI-Angular/issues/73) 91 | * Fix [#74](https://github.com/RaphaelJenni/FirebaseUI-Angular/issues/74) 92 | 93 | ## 3.2.0 94 | * Updated dependencies [#72](https://github.com/RaphaelJenni/FirebaseUI-Angular/pull/72) (Thanks to @arjunyel) 95 | 96 | ## 3.1.1 97 | * Fixed support for Angular < 6 [#68](https://github.com/RaphaelJenni/FirebaseUI-Angular/issues/68) 98 | 99 | ## 3.1.0 100 | * Update project to be compatible with firebaseui v3.1.0 [#63](https://github.com/RaphaelJenni/FirebaseUI-Angular/issues/63) / [#65](https://github.com/RaphaelJenni/FirebaseUI-Angular/issues/65) 101 | * Update Readme with information about the sample project - Fix [#64](https://github.com/RaphaelJenni/FirebaseUI-Angular/issues/64) 102 | 103 | ## 3.0.4 104 | * fix (upgradeAnonymousUser): Enable display with firebaseUI for anonymous user [#59](https://github.com/RaphaelJenni/FirebaseUI-Angular/pull/59) 105 | 106 | ## 3.0.3 107 | * doc update [#58](https://github.com/RaphaelJenni/FirebaseUI-Angular/issues/58) 108 | 109 | ## 3.0.2 110 | * Added missing callbacks (error) option [#53](https://github.com/RaphaelJenni/FirebaseUI-Angular/issues/53) 111 | * Added deprecated firebaseui callback and a flag to disable it (this will be default in the future) 112 | 113 | ## 3.0.1 114 | * Added missing autoUpgradeAnonymousUsers option [#53](https://github.com/RaphaelJenni/FirebaseUI-Angular/issues/53) 115 | * Fixed npm audit 116 | 117 | ## 3.0.0 118 | * Added support for firebaseui@3 and firebase@5 119 | 120 | ## 2.6.2 121 | * Fixed "method" default not working [#40](https://github.com/RaphaelJenni/FirebaseUI-Angular/issues/40) 122 | 123 | ## 2.6.1 124 | * Fixed firebase imports [#32](https://github.com/RaphaelJenni/FirebaseUI-Angular/issues/32) 125 | * Updated build script and all dependencies 126 | 127 | ## 2.6.0 128 | * Fixed firebase imports - [#29](https://github.com/RaphaelJenni/FirebaseUI-Angular/issues/29) 129 | 130 | ## 2.5.3 131 | * Fixed ONE_TAP Login - [pull/30](https://github.com/RaphaelJenni/FirebaseUI-Angular/pull/30) 132 | 133 | ## 2.5.2 134 | * Removed rxjs import 135 | 136 | ## 2.5.1 137 | * Updated README 138 | * Removed deprecated ENUM 139 | 140 | ## 2.5.0 141 | * Fixed [#25](https://github.com/RaphaelJenni/FirebaseUI-Angular/issues/25) 142 | * Updated libraries 143 | * Added one-tap sign-up [#27](https://github.com/RaphaelJenni/FirebaseUI-Angular/issues/27) 144 | 145 | ## 2.4.0 146 | * adjust the plugin version to the firebaseui version 147 | * updated dependency to firebaseui 2.4.0 / angularfire 25.0.0-rc.3 / firebase 4.5.2 148 | 149 | ## 0.4.5 150 | * credentialHelper [#20](https://github.com/RaphaelJenni/FirebaseUI-Angular/issues/20) 151 | 152 | ## 0.4.4 153 | * Lazy loading FirebaseUIModule [#19](https://github.com/RaphaelJenni/FirebaseUI-Angular/issues/19) 154 | 155 | ## 0.4.3 156 | * signInSuccess callback needed [#14](https://github.com/RaphaelJenni/FirebaseUI-Angular/issues/14) 157 | * added a helper file for all the classes and enums 158 | 159 | ## 0.4.2 160 | * Added README to npm 161 | 162 | ## 0.4.1 163 | * Custom configs can be set now 164 | * RedirectUrl can be set now 165 | * Changed enum name AuthProviders -> AuthProvider 166 | 167 | Issue [#8](https://github.com/RaphaelJenni/FirebaseUI-Angular/issues/8) 168 | 169 | ## 0.4.0 170 | * Upgraded to Firebase 4.1.2 / FirebaseUI 2.1.1 / AngularFire 4.0.0-rc.1 171 | * Released version 0.4.0 172 | 173 | Issue [#7](https://github.com/RaphaelJenni/FirebaseUI-Angular/issues/7) 174 | 175 | ## 0.3.0 176 | * Upgraded to Firebase 4.0.0 / FirebaseUI 2.0.0 177 | * Fixed modal showing bug [#5](https://github.com/RaphaelJenni/FirebaseUI-Angular/issues/5) 178 | * Updated sample and readme 179 | 180 | ## 0.2.0 181 | 182 | [Diff](https://github.com/RaphaelJenni/FirebaseUI-Angular/compare/bba132822e26f9e219f9069389423ba25d34dc91...e52710573a720e0724a8d7ecfee960297cc4a112) 183 | * Upgrade to AngularFire 4.0 / Firebase 3.9.0 / Angular 4.1.1 [#2](https://github.com/RaphaelJenni/FirebaseUI-Angular/issues/2) 184 | 185 | 186 | ## 0.1.5 187 | 188 | * FirebaseUI Integration into Angular 189 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /README.MD: -------------------------------------------------------------------------------- 1 | [![Build Status](https://github.com/RaphaelJenni/FirebaseUI-Angular/actions/workflows/firebaseui-angular.yml/badge.svg)](https://github.com/RaphaelJenni/FirebaseUI-Angular/actions/workflows/firebaseui-angular.yml/badge.svg) 2 | [![npm version](https://badge.fury.io/js/firebaseui-angular.svg)](https://badge.fury.io/js/firebaseui-angular) 3 | 4 | # FirebaseUi-Angular 5 | 6 | ![Screenshot of Login screen](https://raw.githubusercontent.com/RaphaelJenni/FirebaseUI-Angular/master/assets/LoginScreen.PNG) 7 | 8 | ## Compatibility 9 | 10 | | Angular | Firebase | AngularFire | FirebaseUI | FirebaseUI-Angular | Note | 11 | |---------|---------|-------------|------------|--------------------|---------------------------------------------------------------------------------------------| 12 | | 18.2.12 | ^11.0.2 | ^18.0.1 | ^6.1.0 | 6.3.0 | | 13 | | 17.1.0 | ^10.7.2 | ^17.0.1 | ^6.1.0 | 6.2.0 | Dropping old Angular and Firbase versions | 14 | | 17.0.0 | ^9.23.0 | ^7.6.1 | ^6.1.0 | 6.1.5 | | 15 | | 16.0.0 | ^9.23.0 | ^7.6.1 | ^6.1.0 | 6.1.4 | | 16 | | 15.0.0 | ^9.14.0 | ^7.5.0 | ^6.0.2 | 6.1.3 | | 17 | | 14.0.2 | ^9.8.3 | ^7.4.1 | ^6.0.1 | 6.1.2 | | 18 | | 13.0.0 | ^9.3.0 | ^7.1.1 | ^6.0.0 | 6.1.0 | | 19 | | 12.1.0 | ^9.0.2 | ^7.0.4 | ^6.0.0 | 6.0.0 | | 20 | | 12.1.0 | ^8.6.8 | ^6.1.5 | ^4.8.0 | 5.1.3 | | 21 | | 11.0.2 | ^8.2.4 | ^6.1.1 | ^4.7.2 | 5.1.2 | *support for [auth emulator](https://firebase.google.com/docs/emulator-suite/connect_auth)* | 22 | | 11.0.2 | ^8.1.1 | ^6.1.1 | ^4.7.1 | 5.1.1 | | 23 | | 10.2.2 | ^8.0.1 | ^6.0.4 | ^4.7.1 | 5.1.0 | | 24 | | ~8.2.13 | ^7.23.0 | ~5.2.1 | ~4.7.1 | ~4.0.1 | | 25 | 26 | Version combinations not documented here __may__ work but are untested. 27 | 28 | ## Installation 29 | 30 | To install this library, run: 31 | 32 | ```bash 33 | $ npm install firebaseui-angular --save 34 | ``` 35 | 36 | To run this library you need to have [AngularFire2](https://github.com/angular/angularfire2) 37 | , [Firebase](https://firebase.google.com/docs/web/setup), 38 | [FirebaseUI-Web](https://github.com/firebase/firebaseui-web) installed. 39 | Fast install: 40 | 41 | ```bash 42 | $ npm install firebase firebaseui @angular/fire firebaseui-angular --save 43 | ``` 44 | 45 | ## How to use 46 | 47 | Add the `FirebaseUIModule` with the config to your imports. Make sure you have 48 | initialized [AngularFire](https://github.com/angular/angularfire2) correctly. 49 | 50 | ```typescript 51 | import {BrowserModule} from '@angular/platform-browser'; 52 | import {NgModule} from '@angular/core'; 53 | import {FormsModule} from '@angular/forms'; 54 | import {AppComponent} from './app.component'; 55 | import {firebase, firebaseui, FirebaseUIModule} from 'firebaseui-angular'; 56 | import {environment} from '../environments/environment'; 57 | import {AppRoutingModule} from './app-routing.module'; 58 | import {AngularFireModule} from "@angular/fire/compat"; 59 | import {AngularFireAuthModule, USE_EMULATOR as USE_AUTH_EMULATOR} from "@angular/fire/compat/auth"; 60 | 61 | 62 | const firebaseUiAuthConfig: firebaseui.auth.Config = { 63 | signInFlow: 'popup', 64 | signInOptions: [ 65 | firebase.auth.GoogleAuthProvider.PROVIDER_ID, 66 | { 67 | scopes: [ 68 | 'public_profile', 69 | 'email', 70 | 'user_likes', 71 | 'user_friends' 72 | ], 73 | customParameters: { 74 | 'auth_type': 'reauthenticate' 75 | }, 76 | provider: firebase.auth.FacebookAuthProvider.PROVIDER_ID 77 | }, 78 | firebase.auth.TwitterAuthProvider.PROVIDER_ID, 79 | firebase.auth.GithubAuthProvider.PROVIDER_ID, 80 | { 81 | requireDisplayName: false, 82 | provider: firebase.auth.EmailAuthProvider.PROVIDER_ID 83 | }, 84 | firebase.auth.PhoneAuthProvider.PROVIDER_ID, 85 | firebaseui.auth.AnonymousAuthProvider.PROVIDER_ID 86 | ], 87 | tosUrl: '', 88 | privacyPolicyUrl: '', 89 | credentialHelper: firebaseui.auth.CredentialHelper.GOOGLE_YOLO 90 | }; 91 | 92 | @NgModule({ 93 | declarations: [ 94 | AppComponent 95 | ], 96 | imports: [ 97 | BrowserModule, 98 | FormsModule, 99 | AppRoutingModule, 100 | AngularFireModule.initializeApp(environment.firebaseConfig), 101 | AngularFireAuthModule, 102 | FirebaseUIModule.forRoot(firebaseUiAuthConfig) 103 | ], 104 | providers: [ 105 | {provide: USE_AUTH_EMULATOR, useValue: !environment.production ? ['localhost', 9099] : undefined}, 106 | ], 107 | bootstrap: [AppComponent] 108 | }) 109 | export class AppModule { 110 | } 111 | 112 | 113 | 114 | 115 | ``` 116 | 117 | ### Add the firebaseui css to your imports: 118 | 119 | **Option 1: CSS Import** 120 | 121 | *May be incompatible with older browsers.* 122 | 123 | Import the firebaseui css to your `src/styles.css` file: 124 | 125 | ```css 126 | @import '~firebaseui/dist/firebaseui.css'; 127 | ``` 128 | 129 | **Option 2: Angular-CLI** 130 | 131 | File: `angular.json` 132 | 133 | Path: `"node_modules/firebaseui/dist/firebaseui.css"` 134 | 135 | ```json 136 | { 137 | "projects": { 138 | [ 139 | your-project-name 140 | ]: { 141 | ... 142 | "architect": { 143 | "build": { 144 | "options": { 145 | ... 146 | "styles": [ 147 | "src/styles.css", 148 | "node_modules/firebaseui/dist/firebaseui.css" 149 | ] 150 | } 151 | }, 152 | ... 153 | "test": { 154 | "options": { 155 | ... 156 | "styles": [ 157 | "src/styles.css", 158 | "node_modules/firebaseui/dist/firebaseui.css" 159 | ] 160 | } 161 | } 162 | } 163 | } 164 | } 165 | } 166 | ``` 167 | 168 | **Option 3: HTML Link** 169 | 170 | Put this in the `` tag of your `index.html` file: 171 | 172 | ```html 173 | 174 | 175 | ``` 176 | 177 | Make sure the version number matches the version of firebaseui you have installed with npm. 178 | 179 | Once everything is set up, you can use the component in your Angular application: 180 | 181 | ```angular2html 182 | 183 | 184 | ``` 185 | 186 | ### Configuration 187 | 188 | For the configuration of the module see the official firebaseui 189 | documentation: [Config](https://github.com/firebase/firebaseui-web#configuration) 190 | 191 | _If you use a version prior to 3.3.0 check 192 | the [old README](https://github.com/RaphaelJenni/FirebaseUI-Angular/blob/v3.2.0/README.MD)_ 193 | 194 | #### forRoot/forFeature 195 | 196 | To configure the plugin the first time (`main.module.ts`) the `forRoot()` method is used. 197 | It builds the basis for all further uses of the plugin. 198 | But you have the possibility to overwrite the entire or just parts of the configuration in any (sub-)module. 199 | 200 | ##### forRoot 201 | 202 | To overwrite the entire configuration use: 203 | 204 | ``` 205 | FirebaseUIModule.forRoot(firebaseUiAuthConfig: NativeFirebaseUIAuthConfig) 206 | ``` 207 | 208 | ##### forFeature 209 | 210 | To overwrite just parts of the configuration use: 211 | 212 | ``` 213 | FirebaseUIModule.forFeature(firebaseUiAuthConfig: NativeFirebaseUIAuthConfig) 214 | ``` 215 | 216 | This will use the in `forRoot` provided configuration and overwrite just the newly provided values. 217 | 218 | ##### Using a Provider Factory 219 | 220 | You may need to dynamically create the firebaseui configuration object based on application settings or the like. An 221 | example of this might be to conditionally enable certain providers for different deployments of the application. 222 | 223 | To do this you can use a provider factory to inject the `firebaseUIAuthConfig` in your module like so: 224 | 225 | ```typescript 226 | providers: [ 227 | { 228 | provide: 'appConfig', 229 | useValue: {googleAuthEnabled: true, emailAuthEnabled: false} 230 | }, 231 | { 232 | provide: 'firebaseUIAuthConfig', 233 | useFactory: (config) => { 234 | 235 | // build firebase UI config object using settings from `config` 236 | 237 | const fbUiConfig: firebaseui.auth.Config = { 238 | signInFlow: 'redirect', 239 | signInOptions: [], 240 | tosUrl: null, 241 | privacyPolicyUrl: null, 242 | credentialHelper: firebaseui.auth.CredentialHelper.GOOGLE_YOLO 243 | }; 244 | 245 | if (config.googleAuthEnabled) { 246 | fbUiConfig.signInOptions.push(firebase.auth.GoogleAuthProvider.PROVIDER_ID); 247 | } 248 | 249 | if (config.emailAuthEnabled) { 250 | fbUiConfig.signInOptions.push({ 251 | provider: firebase.auth.EmailAuthProvider.PROVIDER_ID, 252 | requireDisplayName: true, 253 | signInMethod: firebase.auth.EmailAuthProvider.EMAIL_PASSWORD_SIGN_IN_METHOD 254 | }); 255 | } 256 | 257 | // other providers as needed 258 | 259 | return fbUiConfig; 260 | }, 261 | deps: ['appConfig'] 262 | } 263 | ] 264 | ``` 265 | 266 | In this case we are injecting a settings object `appConfig` into the provider factory. This object contains flags, such 267 | as `googleAuthEnabled` and `emailAuthEnabled` which are used to conditionally build the firebaseui config object. You 268 | would likely use a provider factory for this that reads settings from the environment or database. 269 | 270 | ### Listen to auth state changes 271 | 272 | ```typescript 273 | this.angularFireAuth.authState.subscribe(this.firebaseAuthChangeListener); 274 | 275 | private 276 | firebaseAuthChangeListener(response) 277 | { 278 | // if needed, do a redirect in here 279 | if (response) { 280 | console.log('Logged in :)'); 281 | } else { 282 | console.log('Logged out :('); 283 | } 284 | } 285 | ``` 286 | 287 | Don't forget to unsubscribe at the end. 288 | 289 | ### Sign-in success / failure callbacks 290 | 291 | ```html 292 | 293 | 297 | ``` 298 | 299 | ```typescript 300 | successCallback(signInSuccessData 301 | : 302 | FirebaseUISignInSuccessWithAuthResult 303 | ) 304 | { 305 | ... 306 | } 307 | 308 | errorCallback(errorData 309 | : 310 | FirebaseUISignInFailure 311 | ) 312 | { 313 | ... 314 | } 315 | 316 | uiShownCallback() 317 | { 318 | ... 319 | } 320 | ``` 321 | 322 | ### Disable auto sign-in 323 | 324 | ```typescript 325 | constructor(private 326 | firebaseuiAngularLibraryService: FirebaseuiAngularLibraryService 327 | ) 328 | { 329 | firebaseuiAngularLibraryService.firebaseUiInstance.disableAutoSignIn(); 330 | } 331 | ``` 332 | 333 | ## Internationalizaion (i18n) 334 | 335 | The internationalization with just the npm package of the official firebase-ui isn't possible at the moment. 336 | 337 | For a custom version with i18n support 338 | use: [l0ll098/FirebaseUI-Angular-i18n](https://github.com/l0ll098/FirebaseUI-Angular-i18n) 339 | 340 | Thanks to [@l0ll098](https://github.com/l0ll098)! 341 | 342 | ## Contributing / Sample Application 343 | 344 | Step 1: Fork and clone the repo from Github. 345 | 346 | Step 2: There is a sample project in the root folder. Execute the following command in the root folder i.e. 347 | .../FirebaseUI-Angular > `npm install` 348 | 349 | Step 3: Ensure that you are using Angular CLI version >10. You can check your version with `ng --version` in the 350 | terminal. 351 | 352 | Step 4: Replace with your firebase config in `src\environments\environment.ts`. 353 | 354 | Step 5: .../FirebaseUI-Angular > `npm run build-lib` 355 | 356 | Step 6: .../FirebaseUI-Angular > `ng serve` 357 | 358 | You're welcome to fork the repo and contribute to library sources 359 | in `projects` > `firebaseui-angular-library` > `src` > `lib`. 360 | 361 | There are test files, but they are empty at the moment. Writing unit test is a good start. 362 | 363 | ## Troubleshoot 364 | 365 | ### UI not rendered 366 | 367 | The UI only gets rendered if the user isn't signed in. So if the UI isn't shown, sign out the user via angular-fire. 368 | 369 | ### Prod build error 370 | 371 | ``` 372 | ERROR in ./src/app/app.module.ngfactory.js 373 | Module not found: Error: Can't resolve 'firebase/index' in '...' 374 | ERROR in ./src/app/app.module.ngfactory.js 375 | Module not found: Error: Can't resolve 'firebaseui/dist/index' in '...' 376 | ``` 377 | 378 | Use the firebase and firebaseui instances exposed by the plugin: 379 | 380 | `import {..., firebase, firebaseui} from 'firebaseui-angular';` 381 | 382 | ### CSS not loaded 383 | 384 | If you have added the css to the angular.json but nothing happened. Try to restart the server (`Ctrl-C` and `ng serve`) 385 | 386 | ### ERROR in ./~/firebase/app/shared_promise.js 387 | 388 | This is a know issue in the firebase project. To fix that (for now), do that: 389 | 390 | `npm install promise-polyfill --save-exact` 391 | 392 | ### `http://localhost:4200/images/buffer.svg?embed` 404 (Not Found) 393 | 394 | Put this into your styles.scss file: 395 | 396 | ``` 397 | @supports (-webkit-appearance:none) { 398 | .mdl-progress:not(.mdl-progress--indeterminate):not(.mdl-progress--indeterminate) > .auxbar, 399 | .mdl-progress:not(.mdl-progress__indeterminate):not(.mdl-progress__indeterminate) > .auxbar { 400 | mask: url(/assets/images/buffer.svg?embed) !important; 401 | } 402 | } 403 | ``` 404 | 405 | and put a `buffer.svg` file into `assets/images`. 406 | This will stop this error message. 407 | 408 | ## Supporting the Project 409 | 410 | If you like the project and want to support me, I have a 411 | Buy Me A Coffee 412 | page. 413 | 414 | ## License 415 | 416 | MIT © [Raphael Jenni](mailto:info@rjenni.ch) 417 | -------------------------------------------------------------------------------- /angular.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "./node_modules/@angular/cli/lib/config/schema.json", 3 | "cli": { 4 | "analytics": false 5 | }, 6 | "version": 1, 7 | "newProjectRoot": "projects", 8 | "projects": { 9 | "firebaseui-angular": { 10 | "root": "", 11 | "sourceRoot": "src", 12 | "projectType": "application", 13 | "prefix": "fbui-nx", 14 | "schematics": { 15 | "@schematics/angular:component": { 16 | "style": "scss", 17 | "skipTests": true 18 | }, 19 | "@schematics/angular:class": { 20 | "skipTests": true 21 | }, 22 | "@schematics/angular:directive": { 23 | "skipTests": true 24 | }, 25 | "@schematics/angular:guard": { 26 | "skipTests": true 27 | }, 28 | "@schematics/angular:module": { 29 | }, 30 | "@schematics/angular:pipe": { 31 | "skipTests": true 32 | }, 33 | "@schematics/angular:service": { 34 | "skipTests": true 35 | } 36 | }, 37 | "architect": { 38 | "build": { 39 | "builder": "@angular-devkit/build-angular:application", 40 | "options": { 41 | "outputPath": { 42 | "base": "dist/firebaseui-angular" 43 | }, 44 | "index": "src/index.html", 45 | "polyfills": [ 46 | "src/polyfills.ts" 47 | ], 48 | "tsConfig": "src/tsconfig.app.json", 49 | "assets": [ 50 | "src/favicon.ico", 51 | "src/assets" 52 | ], 53 | "styles": [ 54 | "src/styles.scss", 55 | "node_modules/firebaseui/dist/firebaseui.css" 56 | ], 57 | "scripts": [], 58 | "extractLicenses": false, 59 | "sourceMap": true, 60 | "optimization": false, 61 | "namedChunks": true, 62 | "browser": "src/main.ts" 63 | }, 64 | "configurations": { 65 | "production": { 66 | "budgets": [ 67 | { 68 | "type": "anyComponentStyle", 69 | "maximumWarning": "6kb" 70 | } 71 | ], 72 | "fileReplacements": [ 73 | { 74 | "replace": "src/environments/environment.ts", 75 | "with": "src/environments/environment.prod.ts" 76 | } 77 | ], 78 | "optimization": true, 79 | "outputHashing": "all", 80 | "sourceMap": false, 81 | "namedChunks": false, 82 | "extractLicenses": true 83 | } 84 | }, 85 | "defaultConfiguration": "" 86 | }, 87 | "serve": { 88 | "builder": "@angular-devkit/build-angular:dev-server", 89 | "options": { 90 | "buildTarget": "firebaseui-angular:build" 91 | }, 92 | "configurations": { 93 | "production": { 94 | "buildTarget": "firebaseui-angular:build:production" 95 | } 96 | } 97 | }, 98 | "extract-i18n": { 99 | "builder": "@angular-devkit/build-angular:extract-i18n", 100 | "options": { 101 | "buildTarget": "firebaseui-angular:build" 102 | } 103 | }, 104 | "test": { 105 | "builder": "@angular-devkit/build-angular:karma", 106 | "options": { 107 | "main": "src/test.ts", 108 | "polyfills": "src/polyfills.ts", 109 | "tsConfig": "src/tsconfig.spec.json", 110 | "karmaConfig": "src/karma.conf.js", 111 | "styles": [ 112 | "styles.scss" 113 | ], 114 | "scripts": [], 115 | "assets": [ 116 | "src/favicon.ico", 117 | "src/assets" 118 | ] 119 | } 120 | } 121 | } 122 | }, 123 | "firebaseui-angular-e2e": { 124 | "root": "e2e/", 125 | "projectType": "application", 126 | "architect": { 127 | "e2e": { 128 | "builder": "@angular-devkit/build-angular:protractor", 129 | "options": { 130 | "protractorConfig": "e2e/protractor.conf.js", 131 | "devServerTarget": "firebaseui-angular:serve" 132 | } 133 | } 134 | } 135 | }, 136 | "firebaseui-angular-library": { 137 | "root": "projects/firebaseui-angular-library", 138 | "sourceRoot": "projects/firebaseui-angular-library/src", 139 | "projectType": "library", 140 | "prefix": "lib", 141 | "architect": { 142 | "build": { 143 | "builder": "@angular-devkit/build-angular:ng-packagr", 144 | "options": { 145 | "tsConfig": "projects/firebaseui-angular-library/tsconfig.lib.json", 146 | "project": "projects/firebaseui-angular-library/ng-package.json", 147 | }, 148 | "configurations": { 149 | "production": { 150 | "tsConfig": "projects/firebaseui-angular-library/tsconfig.lib.prod.json" 151 | } 152 | } 153 | }, 154 | "test": { 155 | "builder": "@angular-devkit/build-angular:karma", 156 | "options": { 157 | "main": "projects/firebaseui-angular-library/src/test.ts", 158 | "tsConfig": "projects/firebaseui-angular-library/tsconfig.spec.json", 159 | "karmaConfig": "projects/firebaseui-angular-library/karma.conf.js" 160 | } 161 | } 162 | } 163 | } 164 | } 165 | } 166 | -------------------------------------------------------------------------------- /assets/LoginScreen.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RaphaelJenni/FirebaseUI-Angular/4e78bf48e2329bd62e5817b6915b869f08c6a88b/assets/LoginScreen.PNG -------------------------------------------------------------------------------- /e2e/protractor.conf.js: -------------------------------------------------------------------------------- 1 | // Protractor configuration file, see link for more information 2 | // https://github.com/angular/protractor/blob/master/lib/config.ts 3 | 4 | const { SpecReporter } = require('jasmine-spec-reporter'); 5 | 6 | exports.config = { 7 | allScriptsTimeout: 11000, 8 | specs: [ 9 | './src/**/*.e2e-spec.ts' 10 | ], 11 | capabilities: { 12 | 'browserName': 'chrome' 13 | }, 14 | directConnect: true, 15 | baseUrl: 'http://localhost:4200/', 16 | framework: 'jasmine', 17 | jasmineNodeOpts: { 18 | showColors: true, 19 | defaultTimeoutInterval: 30000, 20 | print: function() {} 21 | }, 22 | onPrepare() { 23 | require('ts-node').register({ 24 | project: require('path').join(__dirname, './tsconfig.e2e.json') 25 | }); 26 | jasmine.getEnv().addReporter(new SpecReporter({ spec: { displayStacktrace: true } })); 27 | } 28 | }; -------------------------------------------------------------------------------- /e2e/src/app.e2e-spec.ts: -------------------------------------------------------------------------------- 1 | import { AppPage } from './app.po'; 2 | 3 | describe('workspace-project App', () => { 4 | let page: AppPage; 5 | 6 | beforeEach(() => { 7 | page = new AppPage(); 8 | }); 9 | 10 | it('should display welcome message', () => { 11 | page.navigateTo(); 12 | expect(page.getParagraphText()).toEqual('Welcome to app!'); 13 | }); 14 | }); 15 | -------------------------------------------------------------------------------- /e2e/src/app.po.ts: -------------------------------------------------------------------------------- 1 | import { browser, by, element } from 'protractor'; 2 | 3 | export class AppPage { 4 | navigateTo() { 5 | return browser.get('/'); 6 | } 7 | 8 | getParagraphText() { 9 | return element(by.css('fbui-nx-root h1')).getText(); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /e2e/tsconfig.e2e.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../out-tsc/app", 5 | "module": "commonjs", 6 | "target": "es5", 7 | "types": [ 8 | "jasmine", 9 | "jasminewd2", 10 | "node" 11 | ] 12 | } 13 | } -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "firebaseui-angular", 3 | "version": "0.0.0", 4 | "scripts": { 5 | "ng": "ng", 6 | "start": "ng serve", 7 | "build": "ng build", 8 | "test": "ng test", 9 | "lint": "ng lint", 10 | "e2e": "ng e2e", 11 | "build-lib": "ng build firebaseui-angular-library --configuration production && npx copy README.MD dist/firebaseui-angular-library", 12 | "prerelease": "cd projects/firebaseui-angular-library && npm version prerelease --preid=beta", 13 | "_prepatch": "cd projects/firebaseui-angular-library && npm version prepatch --preid=beta", 14 | "patch": "cd projects/firebaseui-angular-library && npm version patch", 15 | "_preminor": "cd projects/firebaseui-angular-library && npm version preminor --preid=beta", 16 | "minor": "cd projects/firebaseui-angular-library && npm version minor", 17 | "_premajor": "cd projects/firebaseui-angular-library && npm version premajor --preid=beta", 18 | "major": "cd projects/firebaseui-angular-library && npm version major", 19 | "publish-dist": "npm run build-lib && npm publish ./dist/firebaseui-angular-library", 20 | "publish-dist-beta": "npm run build-lib && npm publish ./dist/firebaseui-angular-library --tag beta" 21 | }, 22 | "private": true, 23 | "dependencies": { 24 | "@angular/animations": "18.2.12", 25 | "@angular/common": "18.2.12", 26 | "@angular/compiler": "18.2.12", 27 | "@angular/core": "18.2.12", 28 | "@angular/fire": "^18.0.1", 29 | "@angular/forms": "18.2.12", 30 | "@angular/platform-browser": "18.2.12", 31 | "@angular/platform-browser-dynamic": "18.2.12", 32 | "@angular/router": "18.2.12", 33 | "firebase": "^11.0.2", 34 | "firebaseui": "^6.1.0", 35 | "rxjs": "^7.8.1", 36 | "tslib": "^2.3.0", 37 | "zone.js": "~0.14.10" 38 | }, 39 | "devDependencies": { 40 | "@angular-devkit/build-angular": "^18.2.12", 41 | "@angular/cli": "^18.2.12", 42 | "@angular/compiler-cli": "18.2.12", 43 | "@types/jasmine": "^3.6.1", 44 | "@types/node": "^14.14.6", 45 | "codelyzer": "^6.0.2", 46 | "jasmine-core": "~3.8.0", 47 | "jasmine-spec-reporter": "~5.0.0", 48 | "karma": "~6.3.16", 49 | "karma-chrome-launcher": "~3.1.0", 50 | "karma-coverage": "~2.0.3", 51 | "karma-jasmine": "~4.0.0", 52 | "karma-jasmine-html-reporter": "^1.5.0", 53 | "ng-packagr": "^18.2.1", 54 | "protractor": "^7.0.0", 55 | "ts-node": "^9.0.0", 56 | "tslint": "6.1.3", 57 | "typescript": "5.4.5" 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /projects/firebaseui-angular-library/karma.conf.js: -------------------------------------------------------------------------------- 1 | // Karma configuration file, see link for more information 2 | // https://karma-runner.github.io/1.0/config/configuration-file.html 3 | 4 | module.exports = function (config) { 5 | config.set({ 6 | basePath: '', 7 | frameworks: ['jasmine', '@angular-devkit/build-angular'], 8 | plugins: [ 9 | require('karma-jasmine'), 10 | require('karma-chrome-launcher'), 11 | require('karma-jasmine-html-reporter'), 12 | require('karma-coverage-istanbul-reporter'), 13 | require('@angular-devkit/build-angular/plugins/karma') 14 | ], 15 | client: { 16 | clearContext: false // leave Jasmine Spec Runner output visible in browser 17 | }, 18 | coverageIstanbulReporter: { 19 | dir: require('path').join(__dirname, '../../coverage'), 20 | reports: ['html', 'lcovonly'], 21 | fixWebpackSourcePaths: true 22 | }, 23 | reporters: ['progress', 'kjhtml'], 24 | port: 9876, 25 | colors: true, 26 | logLevel: config.LOG_INFO, 27 | autoWatch: true, 28 | browsers: ['Chrome'], 29 | singleRun: false, 30 | restartOnFileChange: true 31 | }); 32 | }; 33 | -------------------------------------------------------------------------------- /projects/firebaseui-angular-library/ng-package.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "../../node_modules/ng-packagr/ng-package.schema.json", 3 | "dest": "../../dist/firebaseui-angular-library", 4 | "lib": { 5 | "entryFile": "src/public_api.ts" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /projects/firebaseui-angular-library/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "firebaseui-angular", 3 | "version": "6.3.0", 4 | "repository": { 5 | "type": "git", 6 | "url": "https://github.com/RaphaelJenni/firebaseui-angular" 7 | }, 8 | "author": { 9 | "name": "Raphael Jenni", 10 | "email": "info@rjenni.ch" 11 | }, 12 | "keywords": [ 13 | "angular", 14 | "firebase", 15 | "firebaseui", 16 | "angularfire2" 17 | ], 18 | "license": "MIT", 19 | "bugs": { 20 | "url": "https://github.com/RaphaelJenni/firebaseui-angular/issues" 21 | }, 22 | "peerDependencies": { 23 | "@angular/common": "^12.0.0 || ^13.0.0 || ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0", 24 | "@angular/core": "^12.0.0 || ^13.0.0 || ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0", 25 | "@angular/fire": "^6.0.0 || ^7.0.0 || ^17.0.0 || ^18.0.0", 26 | "firebaseui": "^6.0.0", 27 | "firebase": "^8.0.0 || ^9.0.0 || ^10.0.0" 28 | }, 29 | "dependencies": { 30 | "tslib": "^2.0.0" 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /projects/firebaseui-angular-library/src/lib/firebaseui-angular-library.component.spec.ts: -------------------------------------------------------------------------------- 1 | import {async, ComponentFixture, TestBed} from '@angular/core/testing'; 2 | import {FirebaseuiAngularLibraryComponent} from './firebaseui-angular-library.component'; 3 | import {AngularFireAuth} from '@angular/fire/auth'; 4 | import {Subject} from 'rxjs'; 5 | import {User} from 'firebase'; 6 | import {FirebaseuiAngularLibraryService} from './firebaseui-angular-library.service'; 7 | 8 | describe('FirebaseuiAngularLibraryComponent', () => { 9 | let component: FirebaseuiAngularLibraryComponent; 10 | let fixture: ComponentFixture; 11 | let firebaseAuthState: Subject; 12 | 13 | beforeEach(async(() => { 14 | firebaseAuthState = new Subject(); 15 | 16 | TestBed.configureTestingModule({ 17 | imports: [FirebaseuiAngularLibraryComponent], 18 | providers: [ 19 | { 20 | provide: AngularFireAuth, 21 | useValue: new class { 22 | authState = firebaseAuthState.asObservable(); 23 | }() 24 | }, 25 | { 26 | provide: FirebaseuiAngularLibraryService, 27 | useValue: new class { 28 | firebaseUiInstance = {}; 29 | } 30 | }, 31 | { provide: 'firebaseUIAuthConfig', useValue: { main: 'MAIN', overwritten: 'MAIN' } }, 32 | { provide: 'firebaseUIAuthConfigFeature', useValue: { feature: 'FEATURE', overwritten: 'FEATURE' } } 33 | ] 34 | }) 35 | .compileComponents(); 36 | })); 37 | 38 | beforeEach(() => { 39 | fixture = TestBed.createComponent(FirebaseuiAngularLibraryComponent); 40 | component = fixture.componentInstance; 41 | fixture.detectChanges(); 42 | }); 43 | 44 | it('should create', () => { 45 | expect(component).toBeTruthy(); 46 | }); 47 | 48 | describe('firebaseUiConfig', () => { 49 | it('should combine firebaseUiConfig with firebaseUiConfig_Feature', () => { 50 | expect(component.firebaseUiConfig).toEqual({main: 'MAIN', feature: 'FEATURE', overwritten: 'FEATURE'} as any); 51 | }); 52 | }); 53 | }); 54 | -------------------------------------------------------------------------------- /projects/firebaseui-angular-library/src/lib/firebaseui-angular-library.component.ts: -------------------------------------------------------------------------------- 1 | import {Component, EventEmitter, Inject, NgZone, OnDestroy, OnInit, Output} from '@angular/core'; 2 | import {AngularFireAuth} from '@angular/fire/compat/auth'; 3 | import {Subscription} from 'rxjs'; 4 | import { 5 | FirebaseUISignInFailure, 6 | FirebaseUISignInSuccessWithAuthResult, 7 | NativeFirebaseUIAuthConfig, 8 | } from './firebaseui-angular-library.helper'; 9 | import * as firebaseui from 'firebaseui'; 10 | import firebase from 'firebase/compat/app'; 11 | import {FirebaseuiAngularLibraryService} from './firebaseui-angular-library.service'; 12 | import 'firebase/compat/auth'; 13 | import User = firebase.User; 14 | import UserCredential = firebase.auth.UserCredential; 15 | 16 | @Component({ 17 | selector: 'firebase-ui', 18 | template: '
', 19 | standalone: true 20 | }) 21 | export class FirebaseuiAngularLibraryComponent implements OnInit, OnDestroy { 22 | private static readonly COMPUTED_CALLBACKS = 'COMPUTED_CALLBACKS'; 23 | 24 | @Output('signInSuccessWithAuthResult') signInSuccessWithAuthResultCallback: EventEmitter = new EventEmitter(); // tslint:disable-line 25 | @Output('signInFailure') signInFailureCallback: EventEmitter = new EventEmitter(); // tslint:disable-line 26 | @Output('uiShown') uiShownCallback: EventEmitter = new EventEmitter(); // tslint:disable-line 27 | 28 | private subscription: Subscription; 29 | 30 | constructor(private angularFireAuth: AngularFireAuth, 31 | @Inject('firebaseUIAuthConfig') private _firebaseUiConfig: NativeFirebaseUIAuthConfig, 32 | @Inject('firebaseUIAuthConfigFeature') private _firebaseUiConfig_Feature: NativeFirebaseUIAuthConfig, 33 | private ngZone: NgZone, 34 | private firebaseUIService: FirebaseuiAngularLibraryService) { 35 | } 36 | 37 | get firebaseUiConfig(): NativeFirebaseUIAuthConfig { 38 | return { 39 | ...this._firebaseUiConfig, 40 | ...this._firebaseUiConfig_Feature 41 | } as NativeFirebaseUIAuthConfig; 42 | } 43 | 44 | ngOnInit(): void { 45 | this.subscription = this.angularFireAuth.authState.subscribe((value: User) => { 46 | if ((value && value.isAnonymous) || !value) { 47 | if (this.firebaseUiConfig.signInOptions.length !== 0) { 48 | this.firebaseUIPopup(); 49 | } else { 50 | throw new Error('There must be at least one AuthProvider.'); 51 | } 52 | } 53 | }); 54 | } 55 | 56 | ngOnDestroy(): void { 57 | if (!!this.subscription) { 58 | this.subscription.unsubscribe(); 59 | } 60 | } 61 | 62 | private getUIAuthConfig(): NativeFirebaseUIAuthConfig { 63 | if (!(this.firebaseUiConfig as NativeFirebaseUIAuthConfig).callbacks) { 64 | this._firebaseUiConfig[FirebaseuiAngularLibraryComponent.COMPUTED_CALLBACKS] = true; 65 | (this._firebaseUiConfig as NativeFirebaseUIAuthConfig).callbacks = this.getCallbacks(); 66 | } 67 | return (this.firebaseUiConfig as NativeFirebaseUIAuthConfig); 68 | } 69 | 70 | private firebaseUIPopup() { 71 | const firebaseUiInstance = this.firebaseUIService.firebaseUiInstance; 72 | const uiAuthConfig = this.getUIAuthConfig(); 73 | 74 | // Check if callbacks got computed to reset them again after providing the to firebaseui. 75 | // Necessary for allowing updating the firebaseui config during runtime. 76 | let resetCallbacks = false; 77 | if (uiAuthConfig[FirebaseuiAngularLibraryComponent.COMPUTED_CALLBACKS]) { 78 | resetCallbacks = true; 79 | delete uiAuthConfig[FirebaseuiAngularLibraryComponent.COMPUTED_CALLBACKS]; 80 | } 81 | 82 | // show the firebaseui 83 | firebaseUiInstance.start('#firebaseui-auth-container', uiAuthConfig); 84 | 85 | if (resetCallbacks) { 86 | (this._firebaseUiConfig as NativeFirebaseUIAuthConfig).callbacks = null; 87 | } 88 | } 89 | 90 | private getCallbacks(): any { // firebaseui.Callbacks 91 | const signInSuccessWithAuthResultCallback = (authResult: UserCredential, redirectUrl) => { 92 | this.ngZone.run(() => { 93 | this.signInSuccessWithAuthResultCallback.emit({ 94 | authResult, 95 | redirectUrl 96 | }); 97 | }); 98 | return this.firebaseUiConfig.signInSuccessUrl; 99 | }; 100 | 101 | const signInFailureCallback = (error: firebaseui.auth.AuthUIError) => { 102 | this.ngZone.run(() => { 103 | this.signInFailureCallback.emit({ 104 | code: error.code, 105 | credential: error.credential 106 | }); 107 | }); 108 | return Promise.reject(); 109 | }; 110 | 111 | const uiShownCallback = () => { 112 | this.ngZone.run(() => { 113 | this.uiShownCallback.emit(); 114 | }); 115 | }; 116 | 117 | return { 118 | signInSuccessWithAuthResult: signInSuccessWithAuthResultCallback, 119 | signInFailure: signInFailureCallback, 120 | uiShown: uiShownCallback 121 | }; 122 | } 123 | } 124 | -------------------------------------------------------------------------------- /projects/firebaseui-angular-library/src/lib/firebaseui-angular-library.helper.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Created by Raphael Jenni 3 | * Copyright (c) 2017 Raphael Jenni 4 | */ 5 | 6 | import * as firebaseuiOriginal from 'firebaseui'; 7 | import firebaseOriginal from 'firebase/compat/app'; 8 | import UserCredential = firebaseOriginal.auth.UserCredential; 9 | import AuthCredential = firebaseOriginal.auth.AuthCredential; 10 | 11 | export const firebase = firebaseOriginal; 12 | export const firebaseui = firebaseuiOriginal; 13 | 14 | export type NativeFirebaseUIAuthConfig = firebaseuiOriginal.auth.Config; 15 | 16 | 17 | export class FirebaseUISignInSuccessWithAuthResult { 18 | authResult: UserCredential; 19 | redirectUrl: string; 20 | } 21 | 22 | export class FirebaseUISignInFailure { 23 | code: string; 24 | credential: AuthCredential; 25 | } 26 | -------------------------------------------------------------------------------- /projects/firebaseui-angular-library/src/lib/firebaseui-angular-library.module.ts: -------------------------------------------------------------------------------- 1 | import {ModuleWithProviders, NgModule} from '@angular/core'; 2 | import {FirebaseuiAngularLibraryComponent} from './firebaseui-angular-library.component'; 3 | import {CommonModule} from '@angular/common'; 4 | import {NativeFirebaseUIAuthConfig} from './firebaseui-angular-library.helper'; 5 | import {FirebaseuiAngularLibraryService} from './firebaseui-angular-library.service'; 6 | 7 | @NgModule({ 8 | imports: [ 9 | CommonModule, 10 | FirebaseuiAngularLibraryComponent 11 | ], 12 | providers: [FirebaseuiAngularLibraryService], 13 | exports: [FirebaseuiAngularLibraryComponent] 14 | }) 15 | export class FirebaseUIModule { 16 | static forRoot(firebaseUiAuthConfig: NativeFirebaseUIAuthConfig): ModuleWithProviders { 17 | return { 18 | ngModule: FirebaseUIModule, 19 | providers: [ 20 | {provide: 'firebaseUIAuthConfig', useValue: firebaseUiAuthConfig}, 21 | {provide: 'firebaseUIAuthConfigFeature', useValue: {}} 22 | ] 23 | }; 24 | } 25 | 26 | static forFeature(firebaseUIAuthConfig: NativeFirebaseUIAuthConfig | any): ModuleWithProviders { 27 | return { 28 | ngModule: FirebaseUIModule, 29 | providers: [ 30 | {provide: 'firebaseUIAuthConfigFeature', useValue: firebaseUIAuthConfig} 31 | ] 32 | }; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /projects/firebaseui-angular-library/src/lib/firebaseui-angular-library.service.ts: -------------------------------------------------------------------------------- 1 | import { Inject, Injectable, NgZone, Optional } from '@angular/core'; 2 | import * as firebaseui from 'firebaseui'; 3 | import {FIREBASE_APP_NAME, FIREBASE_OPTIONS, FirebaseApp, ɵfirebaseAppFactory} from '@angular/fire/compat'; 4 | import { FirebaseOptions, FirebaseAppSettings } from 'firebase/app'; 5 | 6 | import _firebase from 'firebase/compat/app'; 7 | import { USE_EMULATOR as USE_AUTH_EMULATOR } from '@angular/fire/compat/auth'; 8 | 9 | type UseEmulatorArguments = [string, number]; 10 | 11 | @Injectable() 12 | export class FirebaseuiAngularLibraryService { 13 | public firebaseUiInstance: firebaseui.auth.AuthUI; 14 | 15 | constructor(@Inject(FIREBASE_OPTIONS) options: FirebaseOptions, 16 | @Optional() @Inject(FIREBASE_APP_NAME) nameOrConfig: string | FirebaseAppSettings | null | undefined, 17 | @Optional() @Inject(USE_AUTH_EMULATOR) _useEmulator: any, // can't use the tuple here 18 | zone: NgZone) { 19 | // noinspection JSNonASCIINames 20 | const app: FirebaseApp = ɵfirebaseAppFactory(options, zone, nameOrConfig); 21 | 22 | const useEmulator: UseEmulatorArguments | null = _useEmulator; 23 | 24 | if (!(window).firebaseUiInstance) { 25 | const auth: _firebase.auth.Auth = app.auth(); 26 | if (useEmulator) { 27 | const connectionString = useEmulator[0].startsWith('http') ? useEmulator[0] : `http://${useEmulator.join(':')}`; 28 | auth.useEmulator(connectionString); 29 | } 30 | (window).firebaseUiInstance = new firebaseui.auth.AuthUI(auth); 31 | } 32 | // store the firebaseui instance on the window object to prevent double initialization 33 | this.firebaseUiInstance = (window).firebaseUiInstance as firebaseui.auth.AuthUI; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /projects/firebaseui-angular-library/src/public_api.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Public API Surface of firebaseui-angular-library 3 | */ 4 | 5 | export * from './lib/firebaseui-angular-library.service'; 6 | export * from './lib/firebaseui-angular-library.component'; 7 | export * from './lib/firebaseui-angular-library.helper'; 8 | export * from './lib/firebaseui-angular-library.module'; 9 | -------------------------------------------------------------------------------- /projects/firebaseui-angular-library/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'; 4 | import 'zone.js/testing'; 5 | import { getTestBed } from '@angular/core/testing'; 6 | import { 7 | BrowserDynamicTestingModule, 8 | platformBrowserDynamicTesting 9 | } from '@angular/platform-browser-dynamic/testing'; 10 | 11 | // First, initialize the Angular testing environment. 12 | getTestBed().initTestEnvironment( 13 | BrowserDynamicTestingModule, 14 | platformBrowserDynamicTesting(), { 15 | teardown: { destroyAfterEach: false } 16 | } 17 | ); 18 | -------------------------------------------------------------------------------- /projects/firebaseui-angular-library/tsconfig.lib.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../../out-tsc/lib", 5 | "module": "es6", 6 | "declaration": true, 7 | "inlineSources": true, 8 | "types": [], 9 | "lib": [ 10 | "dom", 11 | "es2018" 12 | ] 13 | }, 14 | "angularCompilerOptions": { 15 | "skipTemplateCodegen": true, 16 | "strictMetadataEmit": true, 17 | "fullTemplateTypeCheck": true, 18 | "strictInjectionParameters": true, 19 | "enableResourceInlining": true, 20 | "compilationMode": "partial" 21 | }, 22 | "exclude": [ 23 | "src/test.ts", 24 | "**/*.spec.ts" 25 | ] 26 | } 27 | -------------------------------------------------------------------------------- /projects/firebaseui-angular-library/tsconfig.lib.prod.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.lib.json", 3 | "angularCompilerOptions": { 4 | "compilationMode": "partial" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /projects/firebaseui-angular-library/tsconfig.spec.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../../out-tsc/spec", 5 | "types": [ 6 | "jasmine", 7 | "node" 8 | ] 9 | }, 10 | "files": [ 11 | "src/test.ts" 12 | ], 13 | "include": [ 14 | "**/*.spec.ts", 15 | "**/*.d.ts" 16 | ] 17 | } 18 | -------------------------------------------------------------------------------- /projects/firebaseui-angular-library/tslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tslint.json", 3 | "rules": { 4 | "directive-selector": [ 5 | true, 6 | "attribute", 7 | "", 8 | "camelCase" 9 | ], 10 | "component-selector": [ 11 | true, 12 | "element", 13 | "", 14 | "kebab-case" 15 | ] 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/.browserslistrc: -------------------------------------------------------------------------------- 1 | # This file is currently used by autoprefixer to adjust CSS to support the below specified browsers 2 | # For additional information regarding the format and rule options, please see: 3 | # https://github.com/browserslist/browserslist#queries 4 | # For IE 9-11 support, please uncomment the last line of the file and adjust as needed 5 | > 0.5% 6 | last 2 versions 7 | Firefox ESR 8 | not dead 9 | # IE 9-11 -------------------------------------------------------------------------------- /src/app/app-routing.module.ts: -------------------------------------------------------------------------------- 1 | import {NgModule} from '@angular/core'; 2 | import {RouterModule, Routes} from '@angular/router'; 3 | 4 | const routes: Routes = [ 5 | {path: 'page', loadChildren: () => import('./second-page/second.module').then(m => m.SecondModule)}, 6 | {path: '', loadChildren: () => import('./main/main.module').then(m => m.MainModule)}, 7 | ]; 8 | 9 | @NgModule({ 10 | imports: [RouterModule.forRoot(routes)], 11 | exports: [RouterModule], 12 | }) 13 | export class AppRoutingModule { 14 | } 15 | 16 | -------------------------------------------------------------------------------- /src/app/app.component.html: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /src/app/app.component.scss: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RaphaelJenni/FirebaseUI-Angular/4e78bf48e2329bd62e5817b6915b869f08c6a88b/src/app/app.component.scss -------------------------------------------------------------------------------- /src/app/app.component.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | import { RouterOutlet } from '@angular/router'; 3 | 4 | @Component({ 5 | selector: 'fbui-ng-root', 6 | templateUrl: './app.component.html', 7 | styleUrls: ['./app.component.scss'], 8 | standalone: true, 9 | imports: [RouterOutlet] 10 | }) 11 | export class AppComponent { 12 | 13 | } 14 | -------------------------------------------------------------------------------- /src/app/main/main.component.html: -------------------------------------------------------------------------------- 1 |

FirebaseUI-Angular Sample

2 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /src/app/main/main.component.scss: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RaphaelJenni/FirebaseUI-Angular/4e78bf48e2329bd62e5817b6915b869f08c6a88b/src/app/main/main.component.scss -------------------------------------------------------------------------------- /src/app/main/main.component.ts: -------------------------------------------------------------------------------- 1 | import {Component, OnInit} from '@angular/core'; 2 | import {AngularFireAuth} from '@angular/fire/compat/auth'; 3 | import { FirebaseUISignInFailure, FirebaseUISignInSuccessWithAuthResult, FirebaseUIModule } from 'firebaseui-angular'; 4 | import { Router, RouterLink } from '@angular/router'; 5 | 6 | @Component({ 7 | selector: 'fbui-ng-main', 8 | templateUrl: './main.component.html', 9 | styleUrls: ['./main.component.scss'], 10 | standalone: true, 11 | imports: [FirebaseUIModule, RouterLink] 12 | }) 13 | export class MainComponent implements OnInit { 14 | 15 | 16 | constructor(private afAuth: AngularFireAuth, private router: Router) { 17 | } 18 | 19 | ngOnInit(): void { 20 | this.afAuth.authState.subscribe(d => console.log(d)); 21 | } 22 | 23 | logout() { 24 | this.afAuth.signOut(); 25 | } 26 | 27 | successCallback(data: FirebaseUISignInSuccessWithAuthResult) { 28 | console.log('successCallback', data); 29 | this.router.navigate(['page']); 30 | } 31 | 32 | errorCallback(data: FirebaseUISignInFailure) { 33 | console.warn('errorCallback', data); 34 | } 35 | 36 | uiShownCallback() { 37 | console.log('UI shown'); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/app/main/main.module.ts: -------------------------------------------------------------------------------- 1 | import {NgModule} from '@angular/core'; 2 | import {CommonModule} from '@angular/common'; 3 | import {MainComponent} from './main.component'; 4 | import {FirebaseUIModule} from 'firebaseui-angular'; 5 | import {RouterModule, Routes} from '@angular/router'; 6 | 7 | const routes: Routes = [ 8 | {path: '', component: MainComponent}, 9 | ]; 10 | 11 | @NgModule({ 12 | imports: [ 13 | CommonModule, 14 | FirebaseUIModule.forFeature({ tosUrl: 'MAIN_MODULE' }), 15 | RouterModule.forChild(routes), 16 | MainComponent 17 | ] 18 | }) 19 | export class MainModule { 20 | } 21 | -------------------------------------------------------------------------------- /src/app/second-page/second-page.component.html: -------------------------------------------------------------------------------- 1 |

2 | second-page works 3 |

4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /src/app/second-page/second-page.component.scss: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RaphaelJenni/FirebaseUI-Angular/4e78bf48e2329bd62e5817b6915b869f08c6a88b/src/app/second-page/second-page.component.scss -------------------------------------------------------------------------------- /src/app/second-page/second-page.component.ts: -------------------------------------------------------------------------------- 1 | import {Component, OnInit} from '@angular/core'; 2 | import {AngularFireAuth} from '@angular/fire/compat/auth'; 3 | import { FirebaseUISignInSuccessWithAuthResult, FirebaseUIModule } from 'firebaseui-angular'; 4 | import { RouterLink } from '@angular/router'; 5 | 6 | @Component({ 7 | selector: 'fbui-ng-second-page', 8 | templateUrl: './second-page.component.html', 9 | styleUrls: ['./second-page.component.scss'], 10 | standalone: true, 11 | imports: [FirebaseUIModule, RouterLink] 12 | }) 13 | export class SecondPageComponent implements OnInit { 14 | 15 | constructor(private afAuth: AngularFireAuth) { 16 | } 17 | 18 | ngOnInit(): void { 19 | this.afAuth.authState.subscribe(d => console.log(d)); 20 | } 21 | 22 | logout() { 23 | this.afAuth.signOut(); 24 | } 25 | 26 | successCallback(data: FirebaseUISignInSuccessWithAuthResult) { 27 | console.log(data); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/app/second-page/second.module.ts: -------------------------------------------------------------------------------- 1 | import {NgModule} from '@angular/core'; 2 | import {CommonModule} from '@angular/common'; 3 | import {SecondPageComponent} from './second-page.component'; 4 | import {RouterModule, Routes} from '@angular/router'; 5 | import {firebase, FirebaseUIModule} from 'firebaseui-angular'; 6 | 7 | const routes: Routes = [ 8 | {path: '', component: SecondPageComponent}, 9 | ]; 10 | 11 | 12 | @NgModule({ 13 | imports: [ 14 | CommonModule, 15 | FirebaseUIModule.forFeature({ 16 | signInOptions: [ 17 | firebase.auth.GoogleAuthProvider.PROVIDER_ID 18 | ] 19 | }), 20 | RouterModule.forChild(routes), 21 | SecondPageComponent 22 | ] 23 | }) 24 | export class SecondModule { 25 | } 26 | -------------------------------------------------------------------------------- /src/assets/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RaphaelJenni/FirebaseUI-Angular/4e78bf48e2329bd62e5817b6915b869f08c6a88b/src/assets/.gitkeep -------------------------------------------------------------------------------- /src/environments/environment.prod.ts: -------------------------------------------------------------------------------- 1 | export const environment = { 2 | production: true 3 | }; 4 | -------------------------------------------------------------------------------- /src/environments/environment.ts: -------------------------------------------------------------------------------- 1 | // This file can be replaced during build by using the `fileReplacements` array. 2 | // `ng build ---prod` replaces `environment.ts` with `environment.prod.ts`. 3 | // The list of file replacements can be found in `angular.json`. 4 | 5 | export const environment = { 6 | production: false, 7 | firebaseConfig: { 8 | apiKey: '', 9 | authDomain: '', 10 | databaseURL: '', 11 | projectId: '', 12 | storageBucket: '', 13 | messagingSenderId: '' 14 | } 15 | }; 16 | 17 | 18 | /* 19 | * In development mode, to ignore zone related error stack frames such as 20 | * `zone.run`, `zoneDelegate.invokeTask` for easier debugging, you can 21 | * import the following file, but please comment it out in production mode 22 | * because it will have performance impact when throw error 23 | */ 24 | // import 'zone.js/plugins/zone-error'; // Included with Angular CLI. 25 | -------------------------------------------------------------------------------- /src/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RaphaelJenni/FirebaseUI-Angular/4e78bf48e2329bd62e5817b6915b869f08c6a88b/src/favicon.ico -------------------------------------------------------------------------------- /src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | FirebaseuiAngular 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /src/karma.conf.js: -------------------------------------------------------------------------------- 1 | // Karma configuration file, see link for more information 2 | // https://karma-runner.github.io/1.0/config/configuration-file.html 3 | 4 | module.exports = function (config) { 5 | config.set({ 6 | basePath: '', 7 | frameworks: ['jasmine', '@angular-devkit/build-angular'], 8 | plugins: [ 9 | require('karma-jasmine'), 10 | require('karma-chrome-launcher'), 11 | require('karma-jasmine-html-reporter'), 12 | require('karma-coverage-istanbul-reporter'), 13 | require('@angular-devkit/build-angular/plugins/karma') 14 | ], 15 | client: { 16 | clearContext: false // leave Jasmine Spec Runner output visible in browser 17 | }, 18 | coverageIstanbulReporter: { 19 | dir: require('path').join(__dirname, '../coverage'), 20 | reports: ['html', 'lcovonly'], 21 | fixWebpackSourcePaths: true 22 | }, 23 | reporters: ['progress', 'kjhtml'], 24 | port: 9876, 25 | colors: true, 26 | logLevel: config.LOG_INFO, 27 | autoWatch: true, 28 | browsers: ['Chrome'], 29 | singleRun: false 30 | }); 31 | }; -------------------------------------------------------------------------------- /src/main.ts: -------------------------------------------------------------------------------- 1 | import {enableProdMode, importProvidersFrom} from '@angular/core'; 2 | 3 | 4 | import {environment} from './environments/environment'; 5 | import {AppComponent} from './app/app.component'; 6 | import {firebase, firebaseui, FirebaseUIModule} from 'firebaseui-angular'; 7 | import {AngularFireAuthModule} from '@angular/fire/compat/auth'; 8 | import {AngularFireModule} from '@angular/fire/compat'; 9 | import {AppRoutingModule} from './app/app-routing.module'; 10 | import {FormsModule} from '@angular/forms'; 11 | import {bootstrapApplication, BrowserModule} from '@angular/platform-browser'; 12 | 13 | const firebaseUiAuthConfig: firebaseui.auth.Config = { 14 | signInFlow: 'popup', 15 | signInOptions: [ 16 | firebase.auth.GoogleAuthProvider.PROVIDER_ID, 17 | { 18 | scopes: [ 19 | 'public_profile', 20 | 'email', 21 | 'user_likes', 22 | 'user_friends' 23 | ], 24 | customParameters: { 25 | 'auth_type': 'reauthenticate' 26 | }, 27 | provider: firebase.auth.FacebookAuthProvider.PROVIDER_ID 28 | }, 29 | firebase.auth.TwitterAuthProvider.PROVIDER_ID, 30 | firebase.auth.GithubAuthProvider.PROVIDER_ID, 31 | { 32 | requireDisplayName: false, 33 | provider: firebase.auth.EmailAuthProvider.PROVIDER_ID 34 | }, 35 | firebase.auth.PhoneAuthProvider.PROVIDER_ID, 36 | firebaseui.auth.AnonymousAuthProvider.PROVIDER_ID 37 | ], 38 | tosUrl: '', 39 | privacyPolicyUrl: '', 40 | credentialHelper: firebaseui.auth.CredentialHelper.GOOGLE_YOLO 41 | }; 42 | 43 | 44 | if (environment.production) { 45 | enableProdMode(); 46 | } 47 | 48 | bootstrapApplication(AppComponent, { 49 | providers: [importProvidersFrom( 50 | BrowserModule, 51 | FormsModule, 52 | AppRoutingModule, 53 | AngularFireModule.initializeApp(environment.firebaseConfig), 54 | AngularFireAuthModule, 55 | FirebaseUIModule.forRoot(firebaseUiAuthConfig))] 56 | }) 57 | .catch(err => console.log(err)); 58 | -------------------------------------------------------------------------------- /src/polyfills.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * This file includes polyfills needed by Angular and is loaded before the app. 3 | * You can add your own extra polyfills to this file. 4 | * 5 | * This file is divided into 2 sections: 6 | * 1. Browser polyfills. These are applied before loading ZoneJS and are sorted by browsers. 7 | * 2. Application imports. Files imported after ZoneJS that should be loaded before your main 8 | * file. 9 | * 10 | * The current setup is for so-called "evergreen" browsers; the last versions of browsers that 11 | * automatically update themselves. This includes Safari >= 10, Chrome >= 55 (including Opera), 12 | * Edge >= 13 on the desktop, and iOS 10 and Chrome on mobile. 13 | * 14 | * Learn more in https://angular.io/docs/ts/latest/guide/browser-support.html 15 | */ 16 | 17 | /*************************************************************************************************** 18 | * BROWSER POLYFILLS 19 | */ 20 | 21 | /** IE9, IE10 and IE11 requires all of the following polyfills. **/ 22 | // import 'core-js/es6/symbol'; 23 | // import 'core-js/es6/object'; 24 | // import 'core-js/es6/function'; 25 | // import 'core-js/es6/parse-int'; 26 | // import 'core-js/es6/parse-float'; 27 | // import 'core-js/es6/number'; 28 | // import 'core-js/es6/math'; 29 | // import 'core-js/es6/string'; 30 | // import 'core-js/es6/date'; 31 | // import 'core-js/es6/array'; 32 | // import 'core-js/es6/regexp'; 33 | // import 'core-js/es6/map'; 34 | // import 'core-js/es6/weak-map'; 35 | // import 'core-js/es6/set'; 36 | 37 | /** IE10 and IE11 requires the following for the Reflect API. */ 38 | // import 'core-js/es6/reflect'; 39 | 40 | 41 | /** Evergreen browsers require these. **/ 42 | // Used for reflect-metadata in JIT. If you use AOT (and only Angular decorators), you can remove. 43 | 44 | /** 45 | * By default, zone.js will patch all possible macroTask and DomEvents 46 | * user can disable parts of macroTask/DomEvents patch by setting following flags 47 | */ 48 | 49 | // (window as any).__Zone_disable_requestAnimationFrame = true; // disable patch requestAnimationFrame 50 | // (window as any).__Zone_disable_on_property = true; // disable patch onProperty such as onclick 51 | // (window as any).__zone_symbol__BLACK_LISTED_EVENTS = ['scroll', 'mousemove']; // disable patch specified eventNames 52 | 53 | /* 54 | * in IE/Edge developer tools, the addEventListener will also be wrapped by zone.js 55 | * with the following flag, it will bypass `zone.js` patch for IE/Edge 56 | */ 57 | // (window as any).__Zone_enable_cross_context_check = true; 58 | 59 | /*************************************************************************************************** 60 | * Zone JS is required by default for Angular itself. 61 | */ 62 | import 'zone.js'; // Included with Angular CLI. 63 | 64 | 65 | 66 | /*************************************************************************************************** 67 | * APPLICATION IMPORTS 68 | */ 69 | -------------------------------------------------------------------------------- /src/styles.scss: -------------------------------------------------------------------------------- 1 | /* You can add global styles to this file, and also import other style files */ 2 | -------------------------------------------------------------------------------- /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/testing'; 4 | import { getTestBed } from '@angular/core/testing'; 5 | import { 6 | BrowserDynamicTestingModule, 7 | platformBrowserDynamicTesting 8 | } from '@angular/platform-browser-dynamic/testing'; 9 | 10 | // First, initialize the Angular testing environment. 11 | getTestBed().initTestEnvironment( 12 | BrowserDynamicTestingModule, 13 | platformBrowserDynamicTesting(), { 14 | teardown: { destroyAfterEach: false } 15 | } 16 | ); 17 | -------------------------------------------------------------------------------- /src/tsconfig.app.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../out-tsc/app", 5 | "types": [] 6 | }, 7 | "files": [ 8 | "main.ts", 9 | "polyfills.ts" 10 | ], 11 | "include": [ 12 | "src/**/*.d.ts" 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /src/tsconfig.spec.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../out-tsc/spec", 5 | "types": [ 6 | "jasmine", 7 | "node" 8 | ] 9 | }, 10 | "files": [ 11 | "test.ts", 12 | "polyfills.ts" 13 | ], 14 | "include": [ 15 | "**/*.spec.ts", 16 | "**/*.d.ts" 17 | ] 18 | } 19 | -------------------------------------------------------------------------------- /src/tslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tslint.json", 3 | "rules": { 4 | "directive-selector": [ 5 | true, 6 | "attribute", 7 | "fbui-ng", 8 | "camelCase" 9 | ], 10 | "component-selector": [ 11 | true, 12 | "element", 13 | "fbui-ng", 14 | "kebab-case" 15 | ] 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compileOnSave": false, 3 | "compilerOptions": { 4 | "baseUrl": "./", 5 | "importHelpers": true, 6 | "module": "es2020", 7 | "esModuleInterop": true, 8 | "outDir": "./dist/out-tsc", 9 | "sourceMap": true, 10 | "declaration": false, 11 | "moduleResolution": "node", 12 | "experimentalDecorators": true, 13 | "target": "ES2022", 14 | "typeRoots": [ 15 | "node_modules/@types" 16 | ], 17 | "lib": [ 18 | "es2017", 19 | "dom" 20 | ], 21 | "paths": { 22 | "firebaseui-angular": [ 23 | "dist/firebaseui-angular-library" 24 | ], 25 | "firebaseui-angular/*": [ 26 | "dist/firebaseui-angular-library/*" 27 | ] 28 | }, 29 | "useDefineForClassFields": false 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /tslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "rulesDirectory": [ 3 | "node_modules/codelyzer" 4 | ], 5 | "rules": { 6 | "arrow-return-shorthand": true, 7 | "callable-types": true, 8 | "class-name": true, 9 | "comment-format": [ 10 | true, 11 | "check-space" 12 | ], 13 | "curly": true, 14 | "deprecation": { 15 | "severity": "warn" 16 | }, 17 | "eofline": true, 18 | "forin": true, 19 | "import-blacklist": [ 20 | true, 21 | "rxjs/Rx" 22 | ], 23 | "import-spacing": true, 24 | "indent": [ 25 | true, 26 | "spaces" 27 | ], 28 | "interface-over-type-literal": true, 29 | "label-position": true, 30 | "max-line-length": [ 31 | true, 32 | 140 33 | ], 34 | "member-access": false, 35 | "member-ordering": [ 36 | true, 37 | { 38 | "order": [ 39 | "static-field", 40 | "instance-field", 41 | "static-method", 42 | "instance-method" 43 | ] 44 | } 45 | ], 46 | "no-arg": true, 47 | "no-bitwise": true, 48 | "no-console": [ 49 | true, 50 | "debug", 51 | "info", 52 | "time", 53 | "timeEnd", 54 | "trace" 55 | ], 56 | "no-construct": true, 57 | "no-debugger": true, 58 | "no-duplicate-super": true, 59 | "no-empty": false, 60 | "no-empty-interface": true, 61 | "no-eval": true, 62 | "no-inferrable-types": [ 63 | true, 64 | "ignore-params" 65 | ], 66 | "no-misused-new": true, 67 | "no-non-null-assertion": true, 68 | "no-shadowed-variable": true, 69 | "no-string-literal": false, 70 | "no-string-throw": true, 71 | "no-switch-case-fall-through": true, 72 | "no-trailing-whitespace": true, 73 | "no-unnecessary-initializer": true, 74 | "no-unused-expression": true, 75 | "no-var-keyword": true, 76 | "object-literal-sort-keys": false, 77 | "one-line": [ 78 | true, 79 | "check-open-brace", 80 | "check-catch", 81 | "check-else", 82 | "check-whitespace" 83 | ], 84 | "prefer-const": true, 85 | "quotemark": [ 86 | true, 87 | "single" 88 | ], 89 | "radix": true, 90 | "semicolon": [ 91 | true, 92 | "always" 93 | ], 94 | "triple-equals": [ 95 | true, 96 | "allow-null-check" 97 | ], 98 | "typedef-whitespace": [ 99 | true, 100 | { 101 | "call-signature": "nospace", 102 | "index-signature": "nospace", 103 | "parameter": "nospace", 104 | "property-declaration": "nospace", 105 | "variable-declaration": "nospace" 106 | } 107 | ], 108 | "unified-signatures": true, 109 | "variable-name": false, 110 | "whitespace": [ 111 | true, 112 | "check-branch", 113 | "check-decl", 114 | "check-operator", 115 | "check-separator", 116 | "check-type" 117 | ], 118 | "no-output-on-prefix": true, 119 | "use-input-property-decorator": true, 120 | "use-output-property-decorator": true, 121 | "use-host-property-decorator": true, 122 | "no-input-rename": true, 123 | "no-output-rename": true, 124 | "use-life-cycle-interface": true, 125 | "use-pipe-transform-interface": true, 126 | "component-class-suffix": true, 127 | "directive-class-suffix": true 128 | } 129 | } 130 | --------------------------------------------------------------------------------