├── .firebaserc
├── .gitignore
├── README.md
├── angular.json
├── browserslist
├── capacitor.config.json
├── e2e
├── protractor.conf.js
├── src
│ ├── app.e2e-spec.ts
│ └── app.po.ts
└── tsconfig.json
├── firebase.json
├── ionic-v3
├── .editorconfig
├── .gitignore
├── LICENSE
├── README.md
├── config.xml
├── ionic.config.json
├── package-lock.json
├── package.json
├── resources
│ ├── README.md
│ ├── android
│ │ ├── icon
│ │ │ ├── drawable-hdpi-icon.png
│ │ │ ├── drawable-ldpi-icon.png
│ │ │ ├── drawable-mdpi-icon.png
│ │ │ ├── drawable-xhdpi-icon.png
│ │ │ ├── drawable-xxhdpi-icon.png
│ │ │ └── drawable-xxxhdpi-icon.png
│ │ └── splash
│ │ │ ├── drawable-land-hdpi-screen.png
│ │ │ ├── drawable-land-ldpi-screen.png
│ │ │ ├── drawable-land-mdpi-screen.png
│ │ │ ├── drawable-land-xhdpi-screen.png
│ │ │ ├── drawable-land-xxhdpi-screen.png
│ │ │ ├── drawable-land-xxxhdpi-screen.png
│ │ │ ├── drawable-port-hdpi-screen.png
│ │ │ ├── drawable-port-ldpi-screen.png
│ │ │ ├── drawable-port-mdpi-screen.png
│ │ │ ├── drawable-port-xhdpi-screen.png
│ │ │ ├── drawable-port-xxhdpi-screen.png
│ │ │ └── drawable-port-xxxhdpi-screen.png
│ ├── icon.png
│ ├── icon.png.md5
│ ├── ios
│ │ ├── icon
│ │ │ ├── icon-1024.png
│ │ │ ├── icon-40.png
│ │ │ ├── icon-40@2x.png
│ │ │ ├── icon-40@3x.png
│ │ │ ├── icon-50.png
│ │ │ ├── icon-50@2x.png
│ │ │ ├── icon-60.png
│ │ │ ├── icon-60@2x.png
│ │ │ ├── icon-60@3x.png
│ │ │ ├── icon-72.png
│ │ │ ├── icon-72@2x.png
│ │ │ ├── icon-76.png
│ │ │ ├── icon-76@2x.png
│ │ │ ├── icon-83.5@2x.png
│ │ │ ├── icon-small.png
│ │ │ ├── icon-small@2x.png
│ │ │ ├── icon-small@3x.png
│ │ │ ├── icon.png
│ │ │ └── icon@2x.png
│ │ └── splash
│ │ │ ├── Default-568h@2x~iphone.png
│ │ │ ├── Default-667h.png
│ │ │ ├── Default-736h.png
│ │ │ ├── Default-Landscape-736h.png
│ │ │ ├── Default-Landscape@2x~ipad.png
│ │ │ ├── Default-Landscape@~ipadpro.png
│ │ │ ├── Default-Landscape~ipad.png
│ │ │ ├── Default-Portrait@2x~ipad.png
│ │ │ ├── Default-Portrait@~ipadpro.png
│ │ │ ├── Default-Portrait~ipad.png
│ │ │ ├── Default@2x~iphone.png
│ │ │ ├── Default@2x~universal~anyany.png
│ │ │ └── Default~iphone.png
│ ├── splash.png
│ └── splash.png.md5
├── src
│ ├── app
│ │ ├── app.component.ts
│ │ ├── app.html
│ │ ├── app.module.ts
│ │ ├── app.scss
│ │ └── main.ts
│ ├── assets
│ │ ├── icon
│ │ │ └── favicon.ico
│ │ └── imgs
│ │ │ └── logo.png
│ ├── environment
│ │ └── environment.ts
│ ├── index.html
│ ├── manifest.json
│ ├── pages
│ │ ├── core
│ │ │ ├── auth.service.ts
│ │ │ ├── user.model.ts
│ │ │ └── user.service.ts
│ │ ├── login
│ │ │ ├── login.html
│ │ │ ├── login.scss
│ │ │ └── login.ts
│ │ ├── register
│ │ │ ├── register.html
│ │ │ ├── register.scss
│ │ │ └── register.ts
│ │ └── user
│ │ │ ├── user.html
│ │ │ ├── user.scss
│ │ │ └── user.ts
│ ├── service-worker.js
│ └── theme
│ │ ├── commons.scss
│ │ └── variables.scss
├── tsconfig.json
└── tslint.json
├── ionic.config.json
├── karma.conf.js
├── package-lock.json
├── package.json
├── src
├── app
│ ├── app-routing.module.ts
│ ├── app.component.html
│ ├── app.component.spec.ts
│ ├── app.component.ts
│ ├── app.module.ts
│ ├── firebase-auth.service.ts
│ ├── profile
│ │ ├── profile.model.ts
│ │ ├── profile.module.ts
│ │ ├── profile.page.html
│ │ ├── profile.page.scss
│ │ ├── profile.page.spec.ts
│ │ ├── profile.page.ts
│ │ └── profile.resolver.ts
│ ├── sign-in
│ │ ├── sign-in.module.ts
│ │ ├── sign-in.page.html
│ │ ├── sign-in.page.scss
│ │ ├── sign-in.page.spec.ts
│ │ └── sign-in.page.ts
│ └── sign-up
│ │ ├── sign-up.module.ts
│ │ ├── sign-up.page.html
│ │ ├── sign-up.page.scss
│ │ ├── sign-up.page.spec.ts
│ │ └── sign-up.page.ts
├── assets
│ ├── icon
│ │ └── favicon.png
│ └── shapes.svg
├── environments
│ ├── environment.prod.ts
│ └── environment.ts
├── global.scss
├── index.html
├── main.ts
├── polyfills.ts
├── test.ts
├── theme
│ └── variables.scss
└── zone-flags.ts
├── tsconfig.app.json
├── tsconfig.json
├── tsconfig.spec.json
└── tslint.json
/.firebaserc:
--------------------------------------------------------------------------------
1 | {
2 | "targets": {
3 | "ionic5-firebase-authentication": {
4 | "hosting": {
5 | "app": [
6 | "ionic5-firebase-authentication"
7 | ]
8 | }
9 | }
10 | },
11 | "projects": {
12 | "demo": "ionic5-firebase-authentication"
13 | }
14 | }
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Specifies intentionally untracked files to ignore when using Git
2 | # http://git-scm.com/docs/gitignore
3 |
4 | *~
5 | *.sw[mnpcod]
6 | .tmp
7 | *.tmp
8 | *.tmp.*
9 | *.sublime-project
10 | *.sublime-workspace
11 | .DS_Store
12 | Thumbs.db
13 | UserInterfaceState.xcuserstate
14 | $RECYCLE.BIN/
15 |
16 | *.log
17 | log.txt
18 | npm-debug.log*
19 |
20 | /.idea
21 | /.ionic
22 | /.sass-cache
23 | /.sourcemaps
24 | /.versions
25 | /.vscode
26 | /coverage
27 | /dist
28 | /node_modules
29 | /platforms
30 | /plugins
31 | /www
32 |
33 | .firebase
34 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Ionic Firebase Authentication
2 | Enjoy this free Ionic 5 Firebase demo app and save tons of hours of work!
3 |
4 |
9 |
10 | ## About this ionic demo
11 | This repo is the code of an Ionic 5 starter app that we created as part of the post: **[Ionic Firebase Authentication Tutorial](https://ionicthemes.com/tutorials/about/firebase-authentication-in-ionic-framework-apps). In this post we explain how to perform Social Sign In with Firebase from an Ionic application.**
12 |
13 | Most apps need to know the identity of the user who is using it. Knowing a user's identity allows an app to securely save user data in the cloud and provide a personalized experience across all of the user's devices.
14 |
15 | In this Ionic + Firebase tutorial you will learn how to create an Ionic Framework Application with Firebase Authentication. We will show you how to configure both the Firebase and the Ionic 5 App to enable authentication with social providers such as Google, Facebook and Twitter and also with Email and Password.
16 |
17 | As an example we built this Ionic Framework application that allows users to log in and log out using all of the above mentioned authentication options. Once they log in, they will see a profile page with their basic profile info taken from the authentication provider.
18 |
19 | Read the complete post in https://ionicthemes.com/tutorials/about/firebase-authentication-in-ionic-framework-apps.
20 |
21 | ### Ionic Firebase Starter
22 | This repo is a simple ionic 5 starter app with three pages:
23 | - Sign In
24 | - Sign Up
25 | - Profile
26 |
27 | Find more Ionic tutorials and starter apps in https://ionicthemes.com
28 |
29 | ### Demo
30 | - [Online demo](https://ionic5-firebase-authentication.web.app)
31 |
32 | ## Install this Ionic 5 Firebase App
33 | ```
34 | npm install
35 | ```
36 | ### Browse the app
37 | ```
38 | ionic serve
39 | ```
40 |
41 | ### Get a premium Ionic 5 Starter App with Firebase Integration
42 | If you want a ready-made example of how to use Firebase Authentication in Ionic 5 with Capacitor configurations for iOS and Android, check [Ionic 5 Full Starter App PRO](https://ionicthemes.com/product/ionic5-full-starter-app-pro-version). We spent many hours configuring and testing everything so that you don't have to.
43 |
44 | This template has more than 100 carefully designed views and components, it will help you grasp the best practices and new concepts of Ionic 5.
45 |
46 | It also includes a very complete integration with Firebase which includes:
47 | - Firebase Authentication with different providers:
48 | - Facebook sign in
49 | - Twitter sign in
50 | - Google sign in
51 | - Email/Password sign in
52 | - This implementation works in all environments: web, PWA, mobile apps with Capacitor.
53 | - Firebase CRUD
54 | - Firebase queries
55 |
56 |
57 |
--------------------------------------------------------------------------------
/angular.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "./node_modules/@angular/cli/lib/config/schema.json",
3 | "version": 1,
4 | "defaultProject": "app",
5 | "newProjectRoot": "projects",
6 | "projects": {
7 | "app": {
8 | "root": "",
9 | "sourceRoot": "src",
10 | "projectType": "application",
11 | "prefix": "app",
12 | "schematics": {},
13 | "architect": {
14 | "build": {
15 | "builder": "@angular-devkit/build-angular:browser",
16 | "options": {
17 | "outputPath": "www",
18 | "index": "src/index.html",
19 | "main": "src/main.ts",
20 | "polyfills": "src/polyfills.ts",
21 | "tsConfig": "tsconfig.app.json",
22 | "assets": [
23 | {
24 | "glob": "**/*",
25 | "input": "src/assets",
26 | "output": "assets"
27 | },
28 | {
29 | "glob": "**/*.svg",
30 | "input": "node_modules/ionicons/dist/ionicons/svg",
31 | "output": "./svg"
32 | }
33 | ],
34 | "styles": [
35 | {
36 | "input": "src/theme/variables.scss"
37 | },
38 | {
39 | "input": "src/global.scss"
40 | }
41 | ],
42 | "scripts": []
43 | },
44 | "configurations": {
45 | "production": {
46 | "fileReplacements": [
47 | {
48 | "replace": "src/environments/environment.ts",
49 | "with": "src/environments/environment.prod.ts"
50 | }
51 | ],
52 | "optimization": true,
53 | "outputHashing": "all",
54 | "sourceMap": false,
55 | "extractCss": true,
56 | "namedChunks": false,
57 | "aot": true,
58 | "extractLicenses": true,
59 | "vendorChunk": false,
60 | "buildOptimizer": true,
61 | "budgets": [
62 | {
63 | "type": "initial",
64 | "maximumWarning": "2mb",
65 | "maximumError": "5mb"
66 | }
67 | ]
68 | },
69 | "ci": {
70 | "progress": false
71 | }
72 | }
73 | },
74 | "serve": {
75 | "builder": "@angular-devkit/build-angular:dev-server",
76 | "options": {
77 | "browserTarget": "app:build"
78 | },
79 | "configurations": {
80 | "production": {
81 | "browserTarget": "app:build:production"
82 | },
83 | "ci": {
84 | "progress": false
85 | }
86 | }
87 | },
88 | "extract-i18n": {
89 | "builder": "@angular-devkit/build-angular:extract-i18n",
90 | "options": {
91 | "browserTarget": "app:build"
92 | }
93 | },
94 | "test": {
95 | "builder": "@angular-devkit/build-angular:karma",
96 | "options": {
97 | "main": "src/test.ts",
98 | "polyfills": "src/polyfills.ts",
99 | "tsConfig": "tsconfig.spec.json",
100 | "karmaConfig": "karma.conf.js",
101 | "styles": [],
102 | "scripts": [],
103 | "assets": [
104 | {
105 | "glob": "favicon.ico",
106 | "input": "src/",
107 | "output": "/"
108 | },
109 | {
110 | "glob": "**/*",
111 | "input": "src/assets",
112 | "output": "/assets"
113 | }
114 | ]
115 | },
116 | "configurations": {
117 | "ci": {
118 | "progress": false,
119 | "watch": false
120 | }
121 | }
122 | },
123 | "lint": {
124 | "builder": "@angular-devkit/build-angular:tslint",
125 | "options": {
126 | "tsConfig": [
127 | "tsconfig.app.json",
128 | "tsconfig.spec.json",
129 | "e2e/tsconfig.json"
130 | ],
131 | "exclude": [
132 | "**/node_modules/**"
133 | ]
134 | }
135 | },
136 | "e2e": {
137 | "builder": "@angular-devkit/build-angular:protractor",
138 | "options": {
139 | "protractorConfig": "e2e/protractor.conf.js",
140 | "devServerTarget": "app:serve"
141 | },
142 | "configurations": {
143 | "production": {
144 | "devServerTarget": "app:serve:production"
145 | },
146 | "ci": {
147 | "devServerTarget": "app:serve:ci"
148 | }
149 | }
150 | },
151 | "ionic-cordova-build": {
152 | "builder": "@ionic/angular-toolkit:cordova-build",
153 | "options": {
154 | "browserTarget": "app:build"
155 | },
156 | "configurations": {
157 | "production": {
158 | "browserTarget": "app:build:production"
159 | }
160 | }
161 | },
162 | "ionic-cordova-serve": {
163 | "builder": "@ionic/angular-toolkit:cordova-serve",
164 | "options": {
165 | "cordovaBuildTarget": "app:ionic-cordova-build",
166 | "devServerTarget": "app:serve"
167 | },
168 | "configurations": {
169 | "production": {
170 | "cordovaBuildTarget": "app:ionic-cordova-build:production",
171 | "devServerTarget": "app:serve:production"
172 | }
173 | }
174 | },
175 | "deploy": {
176 | "builder": "@angular/fire:deploy",
177 | "options": {}
178 | }
179 | }
180 | }
181 | },
182 | "cli": {
183 | "defaultCollection": "@ionic/angular-toolkit"
184 | },
185 | "schematics": {
186 | "@ionic/angular-toolkit:component": {
187 | "styleext": "scss"
188 | },
189 | "@ionic/angular-toolkit:page": {
190 | "styleext": "scss"
191 | }
192 | }
193 | }
--------------------------------------------------------------------------------
/browserslist:
--------------------------------------------------------------------------------
1 | # This file is used by the build system to adjust CSS and JS output to support the specified browsers below.
2 | # For additional information regarding the format and rule options, please see:
3 | # https://github.com/browserslist/browserslist#queries
4 |
5 | # You can see what browsers were selected by your queries by running:
6 | # npx browserslist
7 |
8 | > 0.5%
9 | last 2 versions
10 | Firefox ESR
11 | not dead
12 | not IE 9-11 # For IE 9-11 support, remove 'not'.
13 |
--------------------------------------------------------------------------------
/capacitor.config.json:
--------------------------------------------------------------------------------
1 | {
2 | "appId": "io.ionic.starter",
3 | "appName": "ionic5-firebase-authentication",
4 | "bundledWebRuntime": false,
5 | "npmClient": "npm",
6 | "webDir": "www",
7 | "cordova": {}
8 | }
9 |
--------------------------------------------------------------------------------
/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.json')
25 | });
26 | jasmine.getEnv().addReporter(new SpecReporter({ spec: { displayStacktrace: true } }));
27 | }
28 | };
29 |
--------------------------------------------------------------------------------
/e2e/src/app.e2e-spec.ts:
--------------------------------------------------------------------------------
1 | import { AppPage } from './app.po';
2 |
3 | describe('new App', () => {
4 | let page: AppPage;
5 |
6 | beforeEach(() => {
7 | page = new AppPage();
8 | });
9 |
10 | it('should be blank', () => {
11 | page.navigateTo();
12 | expect(page.getParagraphText()).toContain('Start with Ionic UI Components');
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.deepCss('app-root ion-content')).getText();
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/e2e/tsconfig.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 | }
14 |
--------------------------------------------------------------------------------
/firebase.json:
--------------------------------------------------------------------------------
1 | {
2 | "hosting": [
3 | {
4 | "target": "app",
5 | "public": "www",
6 | "ignore": [
7 | "firebase.json",
8 | "**/.*",
9 | "**/node_modules/**"
10 | ],
11 | "rewrites": [
12 | {
13 | "source": "**",
14 | "destination": "/index.html"
15 | }
16 | ]
17 | }
18 | ]
19 | }
--------------------------------------------------------------------------------
/ionic-v3/.editorconfig:
--------------------------------------------------------------------------------
1 | # EditorConfig helps developers define and maintain consistent coding styles between different editors and IDEs
2 | # editorconfig.org
3 |
4 | root = true
5 |
6 | [*]
7 | indent_style = space
8 | indent_size = 2
9 |
10 | # We recommend you to keep these unchanged
11 | end_of_line = lf
12 | charset = utf-8
13 | trim_trailing_whitespace = true
14 | insert_final_newline = true
15 |
16 | [*.md]
17 | trim_trailing_whitespace = false
--------------------------------------------------------------------------------
/ionic-v3/.gitignore:
--------------------------------------------------------------------------------
1 | # Specifies intentionally untracked files to ignore when using Git
2 | # http://git-scm.com/docs/gitignore
3 |
4 | *~
5 | *.sw[mnpcod]
6 | *.log
7 | *.tmp
8 | *.tmp.*
9 | log.txt
10 | *.sublime-project
11 | *.sublime-workspace
12 | .vscode/
13 | npm-debug.log*
14 |
15 | .idea/
16 | .sourcemaps/
17 | .sass-cache/
18 | .tmp/
19 | .versions/
20 | coverage/
21 | dist/
22 | node_modules/
23 | tmp/
24 | temp/
25 | hooks/
26 | platforms/
27 | plugins/
28 | plugins/android.json
29 | plugins/ios.json
30 | www/
31 | $RECYCLE.BIN/
32 |
33 | .DS_Store
34 | Thumbs.db
35 | UserInterfaceState.xcuserstate
36 |
--------------------------------------------------------------------------------
/ionic-v3/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2018 IonicThemes
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 all
13 | 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 THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/ionic-v3/README.md:
--------------------------------------------------------------------------------
1 | ## Firebase Authentication in Ionic Framework Apps
2 |
3 | In this ionic tutorial we will learn how to configure a firebase application to enable an ionic 3 application to log in with both Email and Password and social providers such as Facebook, Twitter and Google.
4 |
5 | This repo is a simple ionic 3 app example with the goal of helping you integration Firebase Authentication to your Ionic app.
6 |
7 | 
8 | 
9 |
10 | **Note:** This code is for Ionic v3.
11 | - If you are working with Ionic v5 go to [ionic-v5 code](https://github.com/ionicthemes/ionic5-firebase-authentication)
12 | - If you are working with Ionic v1 go to [ionic-v1 code](https://github.com/ionicthemes/firebase-authentication-for-your-ionic-app).
13 |
14 | Read the complete Ionic Firebase Authentication Tutorial in https://ionicthemes.com/tutorials/about/firebase-authentication-in-ionic-framework-apps
15 |
--------------------------------------------------------------------------------
/ionic-v3/config.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Firebase Authentication in Ionic Framework Apps
4 | Firebase Authentication example Ionic app
5 | IonicThemes Team
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
--------------------------------------------------------------------------------
/ionic-v3/ionic.config.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "",
3 | "app_id": "",
4 | "integrations": {
5 | "cordova": {}
6 | },
7 | "type": "ionic-angular"
8 | }
9 |
--------------------------------------------------------------------------------
/ionic-v3/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "Ionic3FirebaseLogin",
3 | "version": "0.0.1",
4 | "author": "IonicThemes",
5 | "homepage": "https://ionicthemes.com/",
6 | "private": true,
7 | "scripts": {
8 | "clean": "ionic-app-scripts clean",
9 | "build": "ionic-app-scripts build",
10 | "lint": "ionic-app-scripts lint",
11 | "ionic:build": "ionic-app-scripts build",
12 | "ionic:serve": "ionic-app-scripts serve"
13 | },
14 | "dependencies": {
15 | "@angular/animations": "5.2.10",
16 | "@angular/common": "5.2.10",
17 | "@angular/compiler": "5.2.10",
18 | "@angular/compiler-cli": "5.2.10",
19 | "@angular/core": "5.2.10",
20 | "@angular/forms": "5.2.10",
21 | "@angular/http": "5.2.10",
22 | "@angular/platform-browser": "5.2.10",
23 | "@angular/platform-browser-dynamic": "5.2.10",
24 | "@ionic-native/core": "4.4.0",
25 | "@ionic-native/facebook": "^4.5.3",
26 | "@ionic-native/google-plus": "^4.5.3",
27 | "@ionic-native/splash-screen": "4.4.0",
28 | "@ionic-native/status-bar": "4.4.0",
29 | "@ionic-native/twitter-connect": "^4.5.3",
30 | "@ionic/storage": "2.1.3",
31 | "angularfire2": "^5.0.0-rc.10",
32 | "cordova-android": "6.4.0",
33 | "cordova-ios": "~4.5.4",
34 | "cordova-plugin-device": "^2.0.2",
35 | "cordova-plugin-facebook4": "^1.10.1",
36 | "cordova-plugin-googleplus": "^5.3.0",
37 | "cordova-plugin-ionic-keyboard": "^2.1.2",
38 | "cordova-plugin-ionic-webview": "^1.2.1",
39 | "cordova-plugin-splashscreen": "^5.0.2",
40 | "cordova-plugin-whitelist": "^1.3.3",
41 | "firebase": "^5.0.4",
42 | "ionic-angular": "3.9.2",
43 | "ionicons": "3.0.0",
44 | "rxjs": "^5.5.6",
45 | "sw-toolbox": "3.6.0",
46 | "twitter-connect-plugin": "git+https://github.com/chroa/twitter-connect-plugin.git",
47 | "zone.js": "0.8.18"
48 | },
49 | "devDependencies": {
50 | "@ionic/app-scripts": "3.1.8",
51 | "typescript": "2.4.2"
52 | },
53 | "description": "An Ionic project",
54 | "cordova": {
55 | "platforms": [
56 | "android",
57 | "ios"
58 | ],
59 | "plugins": {
60 | "cordova-plugin-device": {},
61 | "cordova-plugin-facebook4": {
62 | "APP_ID": "186848361921511",
63 | "APP_NAME": "myApplication"
64 | },
65 | "cordova-plugin-googleplus": {
66 | "REVERSED_CLIENT_ID": "com.googleusercontent.apps.401245627689-mcupb7o4sra8p6jqnlhe17d8b2rf4du6"
67 | },
68 | "cordova-plugin-ionic-keyboard": {},
69 | "cordova-plugin-ionic-webview": {},
70 | "cordova-plugin-splashscreen": {},
71 | "cordova-plugin-whitelist": {},
72 | "twitter-connect-plugin": {
73 | "FABRIC_KEY": "dbf48d8f78bb16f9d9c54d737d7792891eb24607",
74 | "TWITTER_KEY": "kMV673U74jFqP3QZ81X4CduYL",
75 | "TWITTER_SECRET": "mb03DWehE5zRcb4g6Yl3PjJXlmCVEoDUxvCskotORCNy503rc4"
76 | }
77 | }
78 | }
79 | }
--------------------------------------------------------------------------------
/ionic-v3/resources/README.md:
--------------------------------------------------------------------------------
1 | These are Cordova resources. You can replace icon.png and splash.png and run
2 | `ionic cordova resources` to generate custom icons and splash screens for your
3 | app. See `ionic cordova resources --help` for details.
4 |
5 | Cordova reference documentation:
6 |
7 | - Icons: https://cordova.apache.org/docs/en/latest/config_ref/images.html
8 | - Splash Screens: https://cordova.apache.org/docs/en/latest/reference/cordova-plugin-splashscreen/
9 |
--------------------------------------------------------------------------------
/ionic-v3/resources/android/icon/drawable-hdpi-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ionicthemes/ionic5-firebase-authentication/c599afaddf333e94b7c7bfc4c906b216c47bb252/ionic-v3/resources/android/icon/drawable-hdpi-icon.png
--------------------------------------------------------------------------------
/ionic-v3/resources/android/icon/drawable-ldpi-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ionicthemes/ionic5-firebase-authentication/c599afaddf333e94b7c7bfc4c906b216c47bb252/ionic-v3/resources/android/icon/drawable-ldpi-icon.png
--------------------------------------------------------------------------------
/ionic-v3/resources/android/icon/drawable-mdpi-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ionicthemes/ionic5-firebase-authentication/c599afaddf333e94b7c7bfc4c906b216c47bb252/ionic-v3/resources/android/icon/drawable-mdpi-icon.png
--------------------------------------------------------------------------------
/ionic-v3/resources/android/icon/drawable-xhdpi-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ionicthemes/ionic5-firebase-authentication/c599afaddf333e94b7c7bfc4c906b216c47bb252/ionic-v3/resources/android/icon/drawable-xhdpi-icon.png
--------------------------------------------------------------------------------
/ionic-v3/resources/android/icon/drawable-xxhdpi-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ionicthemes/ionic5-firebase-authentication/c599afaddf333e94b7c7bfc4c906b216c47bb252/ionic-v3/resources/android/icon/drawable-xxhdpi-icon.png
--------------------------------------------------------------------------------
/ionic-v3/resources/android/icon/drawable-xxxhdpi-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ionicthemes/ionic5-firebase-authentication/c599afaddf333e94b7c7bfc4c906b216c47bb252/ionic-v3/resources/android/icon/drawable-xxxhdpi-icon.png
--------------------------------------------------------------------------------
/ionic-v3/resources/android/splash/drawable-land-hdpi-screen.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ionicthemes/ionic5-firebase-authentication/c599afaddf333e94b7c7bfc4c906b216c47bb252/ionic-v3/resources/android/splash/drawable-land-hdpi-screen.png
--------------------------------------------------------------------------------
/ionic-v3/resources/android/splash/drawable-land-ldpi-screen.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ionicthemes/ionic5-firebase-authentication/c599afaddf333e94b7c7bfc4c906b216c47bb252/ionic-v3/resources/android/splash/drawable-land-ldpi-screen.png
--------------------------------------------------------------------------------
/ionic-v3/resources/android/splash/drawable-land-mdpi-screen.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ionicthemes/ionic5-firebase-authentication/c599afaddf333e94b7c7bfc4c906b216c47bb252/ionic-v3/resources/android/splash/drawable-land-mdpi-screen.png
--------------------------------------------------------------------------------
/ionic-v3/resources/android/splash/drawable-land-xhdpi-screen.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ionicthemes/ionic5-firebase-authentication/c599afaddf333e94b7c7bfc4c906b216c47bb252/ionic-v3/resources/android/splash/drawable-land-xhdpi-screen.png
--------------------------------------------------------------------------------
/ionic-v3/resources/android/splash/drawable-land-xxhdpi-screen.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ionicthemes/ionic5-firebase-authentication/c599afaddf333e94b7c7bfc4c906b216c47bb252/ionic-v3/resources/android/splash/drawable-land-xxhdpi-screen.png
--------------------------------------------------------------------------------
/ionic-v3/resources/android/splash/drawable-land-xxxhdpi-screen.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ionicthemes/ionic5-firebase-authentication/c599afaddf333e94b7c7bfc4c906b216c47bb252/ionic-v3/resources/android/splash/drawable-land-xxxhdpi-screen.png
--------------------------------------------------------------------------------
/ionic-v3/resources/android/splash/drawable-port-hdpi-screen.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ionicthemes/ionic5-firebase-authentication/c599afaddf333e94b7c7bfc4c906b216c47bb252/ionic-v3/resources/android/splash/drawable-port-hdpi-screen.png
--------------------------------------------------------------------------------
/ionic-v3/resources/android/splash/drawable-port-ldpi-screen.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ionicthemes/ionic5-firebase-authentication/c599afaddf333e94b7c7bfc4c906b216c47bb252/ionic-v3/resources/android/splash/drawable-port-ldpi-screen.png
--------------------------------------------------------------------------------
/ionic-v3/resources/android/splash/drawable-port-mdpi-screen.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ionicthemes/ionic5-firebase-authentication/c599afaddf333e94b7c7bfc4c906b216c47bb252/ionic-v3/resources/android/splash/drawable-port-mdpi-screen.png
--------------------------------------------------------------------------------
/ionic-v3/resources/android/splash/drawable-port-xhdpi-screen.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ionicthemes/ionic5-firebase-authentication/c599afaddf333e94b7c7bfc4c906b216c47bb252/ionic-v3/resources/android/splash/drawable-port-xhdpi-screen.png
--------------------------------------------------------------------------------
/ionic-v3/resources/android/splash/drawable-port-xxhdpi-screen.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ionicthemes/ionic5-firebase-authentication/c599afaddf333e94b7c7bfc4c906b216c47bb252/ionic-v3/resources/android/splash/drawable-port-xxhdpi-screen.png
--------------------------------------------------------------------------------
/ionic-v3/resources/android/splash/drawable-port-xxxhdpi-screen.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ionicthemes/ionic5-firebase-authentication/c599afaddf333e94b7c7bfc4c906b216c47bb252/ionic-v3/resources/android/splash/drawable-port-xxxhdpi-screen.png
--------------------------------------------------------------------------------
/ionic-v3/resources/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ionicthemes/ionic5-firebase-authentication/c599afaddf333e94b7c7bfc4c906b216c47bb252/ionic-v3/resources/icon.png
--------------------------------------------------------------------------------
/ionic-v3/resources/icon.png.md5:
--------------------------------------------------------------------------------
1 | 3f1bbdf1aefcb5ce7b60770ce907c68f
--------------------------------------------------------------------------------
/ionic-v3/resources/ios/icon/icon-1024.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ionicthemes/ionic5-firebase-authentication/c599afaddf333e94b7c7bfc4c906b216c47bb252/ionic-v3/resources/ios/icon/icon-1024.png
--------------------------------------------------------------------------------
/ionic-v3/resources/ios/icon/icon-40.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ionicthemes/ionic5-firebase-authentication/c599afaddf333e94b7c7bfc4c906b216c47bb252/ionic-v3/resources/ios/icon/icon-40.png
--------------------------------------------------------------------------------
/ionic-v3/resources/ios/icon/icon-40@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ionicthemes/ionic5-firebase-authentication/c599afaddf333e94b7c7bfc4c906b216c47bb252/ionic-v3/resources/ios/icon/icon-40@2x.png
--------------------------------------------------------------------------------
/ionic-v3/resources/ios/icon/icon-40@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ionicthemes/ionic5-firebase-authentication/c599afaddf333e94b7c7bfc4c906b216c47bb252/ionic-v3/resources/ios/icon/icon-40@3x.png
--------------------------------------------------------------------------------
/ionic-v3/resources/ios/icon/icon-50.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ionicthemes/ionic5-firebase-authentication/c599afaddf333e94b7c7bfc4c906b216c47bb252/ionic-v3/resources/ios/icon/icon-50.png
--------------------------------------------------------------------------------
/ionic-v3/resources/ios/icon/icon-50@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ionicthemes/ionic5-firebase-authentication/c599afaddf333e94b7c7bfc4c906b216c47bb252/ionic-v3/resources/ios/icon/icon-50@2x.png
--------------------------------------------------------------------------------
/ionic-v3/resources/ios/icon/icon-60.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ionicthemes/ionic5-firebase-authentication/c599afaddf333e94b7c7bfc4c906b216c47bb252/ionic-v3/resources/ios/icon/icon-60.png
--------------------------------------------------------------------------------
/ionic-v3/resources/ios/icon/icon-60@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ionicthemes/ionic5-firebase-authentication/c599afaddf333e94b7c7bfc4c906b216c47bb252/ionic-v3/resources/ios/icon/icon-60@2x.png
--------------------------------------------------------------------------------
/ionic-v3/resources/ios/icon/icon-60@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ionicthemes/ionic5-firebase-authentication/c599afaddf333e94b7c7bfc4c906b216c47bb252/ionic-v3/resources/ios/icon/icon-60@3x.png
--------------------------------------------------------------------------------
/ionic-v3/resources/ios/icon/icon-72.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ionicthemes/ionic5-firebase-authentication/c599afaddf333e94b7c7bfc4c906b216c47bb252/ionic-v3/resources/ios/icon/icon-72.png
--------------------------------------------------------------------------------
/ionic-v3/resources/ios/icon/icon-72@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ionicthemes/ionic5-firebase-authentication/c599afaddf333e94b7c7bfc4c906b216c47bb252/ionic-v3/resources/ios/icon/icon-72@2x.png
--------------------------------------------------------------------------------
/ionic-v3/resources/ios/icon/icon-76.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ionicthemes/ionic5-firebase-authentication/c599afaddf333e94b7c7bfc4c906b216c47bb252/ionic-v3/resources/ios/icon/icon-76.png
--------------------------------------------------------------------------------
/ionic-v3/resources/ios/icon/icon-76@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ionicthemes/ionic5-firebase-authentication/c599afaddf333e94b7c7bfc4c906b216c47bb252/ionic-v3/resources/ios/icon/icon-76@2x.png
--------------------------------------------------------------------------------
/ionic-v3/resources/ios/icon/icon-83.5@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ionicthemes/ionic5-firebase-authentication/c599afaddf333e94b7c7bfc4c906b216c47bb252/ionic-v3/resources/ios/icon/icon-83.5@2x.png
--------------------------------------------------------------------------------
/ionic-v3/resources/ios/icon/icon-small.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ionicthemes/ionic5-firebase-authentication/c599afaddf333e94b7c7bfc4c906b216c47bb252/ionic-v3/resources/ios/icon/icon-small.png
--------------------------------------------------------------------------------
/ionic-v3/resources/ios/icon/icon-small@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ionicthemes/ionic5-firebase-authentication/c599afaddf333e94b7c7bfc4c906b216c47bb252/ionic-v3/resources/ios/icon/icon-small@2x.png
--------------------------------------------------------------------------------
/ionic-v3/resources/ios/icon/icon-small@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ionicthemes/ionic5-firebase-authentication/c599afaddf333e94b7c7bfc4c906b216c47bb252/ionic-v3/resources/ios/icon/icon-small@3x.png
--------------------------------------------------------------------------------
/ionic-v3/resources/ios/icon/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ionicthemes/ionic5-firebase-authentication/c599afaddf333e94b7c7bfc4c906b216c47bb252/ionic-v3/resources/ios/icon/icon.png
--------------------------------------------------------------------------------
/ionic-v3/resources/ios/icon/icon@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ionicthemes/ionic5-firebase-authentication/c599afaddf333e94b7c7bfc4c906b216c47bb252/ionic-v3/resources/ios/icon/icon@2x.png
--------------------------------------------------------------------------------
/ionic-v3/resources/ios/splash/Default-568h@2x~iphone.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ionicthemes/ionic5-firebase-authentication/c599afaddf333e94b7c7bfc4c906b216c47bb252/ionic-v3/resources/ios/splash/Default-568h@2x~iphone.png
--------------------------------------------------------------------------------
/ionic-v3/resources/ios/splash/Default-667h.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ionicthemes/ionic5-firebase-authentication/c599afaddf333e94b7c7bfc4c906b216c47bb252/ionic-v3/resources/ios/splash/Default-667h.png
--------------------------------------------------------------------------------
/ionic-v3/resources/ios/splash/Default-736h.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ionicthemes/ionic5-firebase-authentication/c599afaddf333e94b7c7bfc4c906b216c47bb252/ionic-v3/resources/ios/splash/Default-736h.png
--------------------------------------------------------------------------------
/ionic-v3/resources/ios/splash/Default-Landscape-736h.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ionicthemes/ionic5-firebase-authentication/c599afaddf333e94b7c7bfc4c906b216c47bb252/ionic-v3/resources/ios/splash/Default-Landscape-736h.png
--------------------------------------------------------------------------------
/ionic-v3/resources/ios/splash/Default-Landscape@2x~ipad.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ionicthemes/ionic5-firebase-authentication/c599afaddf333e94b7c7bfc4c906b216c47bb252/ionic-v3/resources/ios/splash/Default-Landscape@2x~ipad.png
--------------------------------------------------------------------------------
/ionic-v3/resources/ios/splash/Default-Landscape@~ipadpro.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ionicthemes/ionic5-firebase-authentication/c599afaddf333e94b7c7bfc4c906b216c47bb252/ionic-v3/resources/ios/splash/Default-Landscape@~ipadpro.png
--------------------------------------------------------------------------------
/ionic-v3/resources/ios/splash/Default-Landscape~ipad.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ionicthemes/ionic5-firebase-authentication/c599afaddf333e94b7c7bfc4c906b216c47bb252/ionic-v3/resources/ios/splash/Default-Landscape~ipad.png
--------------------------------------------------------------------------------
/ionic-v3/resources/ios/splash/Default-Portrait@2x~ipad.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ionicthemes/ionic5-firebase-authentication/c599afaddf333e94b7c7bfc4c906b216c47bb252/ionic-v3/resources/ios/splash/Default-Portrait@2x~ipad.png
--------------------------------------------------------------------------------
/ionic-v3/resources/ios/splash/Default-Portrait@~ipadpro.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ionicthemes/ionic5-firebase-authentication/c599afaddf333e94b7c7bfc4c906b216c47bb252/ionic-v3/resources/ios/splash/Default-Portrait@~ipadpro.png
--------------------------------------------------------------------------------
/ionic-v3/resources/ios/splash/Default-Portrait~ipad.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ionicthemes/ionic5-firebase-authentication/c599afaddf333e94b7c7bfc4c906b216c47bb252/ionic-v3/resources/ios/splash/Default-Portrait~ipad.png
--------------------------------------------------------------------------------
/ionic-v3/resources/ios/splash/Default@2x~iphone.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ionicthemes/ionic5-firebase-authentication/c599afaddf333e94b7c7bfc4c906b216c47bb252/ionic-v3/resources/ios/splash/Default@2x~iphone.png
--------------------------------------------------------------------------------
/ionic-v3/resources/ios/splash/Default@2x~universal~anyany.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ionicthemes/ionic5-firebase-authentication/c599afaddf333e94b7c7bfc4c906b216c47bb252/ionic-v3/resources/ios/splash/Default@2x~universal~anyany.png
--------------------------------------------------------------------------------
/ionic-v3/resources/ios/splash/Default~iphone.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ionicthemes/ionic5-firebase-authentication/c599afaddf333e94b7c7bfc4c906b216c47bb252/ionic-v3/resources/ios/splash/Default~iphone.png
--------------------------------------------------------------------------------
/ionic-v3/resources/splash.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ionicthemes/ionic5-firebase-authentication/c599afaddf333e94b7c7bfc4c906b216c47bb252/ionic-v3/resources/splash.png
--------------------------------------------------------------------------------
/ionic-v3/resources/splash.png.md5:
--------------------------------------------------------------------------------
1 | 2412a8324a656ec5993eb50b3b293c69
--------------------------------------------------------------------------------
/ionic-v3/src/app/app.component.ts:
--------------------------------------------------------------------------------
1 | import { Component } from '@angular/core';
2 | import { Platform } from 'ionic-angular';
3 | import { StatusBar } from '@ionic-native/status-bar';
4 | import { SplashScreen } from '@ionic-native/splash-screen';
5 |
6 | import { LoginPage } from '../pages/login/login';
7 | @Component({
8 | templateUrl: 'app.html'
9 | })
10 | export class MyApp {
11 | rootPage:any = LoginPage;
12 |
13 | constructor(platform: Platform, statusBar: StatusBar, splashScreen: SplashScreen) {
14 | platform.ready().then(() => {
15 | // Okay, so the platform is ready and our plugins are available.
16 | // Here you can do any higher level native things you might need.
17 | statusBar.styleDefault();
18 | splashScreen.hide();
19 | });
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/ionic-v3/src/app/app.html:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/ionic-v3/src/app/app.module.ts:
--------------------------------------------------------------------------------
1 | import { BrowserModule } from '@angular/platform-browser';
2 | import { ErrorHandler, NgModule } from '@angular/core';
3 | import { IonicApp, IonicErrorHandler, IonicModule } from 'ionic-angular';
4 | import { SplashScreen } from '@ionic-native/splash-screen';
5 | import { StatusBar } from '@ionic-native/status-bar';
6 |
7 | import { MyApp } from './app.component';
8 | import { LoginPage } from '../pages/login/login';
9 | import { RegisterPage } from '../pages/register/register';
10 | import { UserPage} from '../pages/user/user';
11 |
12 |
13 | import { AuthService } from '../pages/core/auth.service';
14 | import { UserService } from '../pages/core/user.service';
15 |
16 | import { AngularFireModule } from 'angularfire2';
17 | import { AngularFireAuthModule } from 'angularfire2/auth';
18 | import { environment } from '../environment/environment';
19 |
20 | import { Facebook } from '@ionic-native/facebook';
21 | import { GooglePlus } from '@ionic-native/google-plus';
22 | import { TwitterConnect } from '@ionic-native/twitter-connect';
23 |
24 |
25 | @NgModule({
26 | declarations: [
27 | MyApp,
28 | LoginPage,
29 | RegisterPage,
30 | UserPage
31 | ],
32 | imports: [
33 | BrowserModule,
34 | IonicModule.forRoot(MyApp),
35 | AngularFireModule.initializeApp(environment.firebase),
36 | AngularFireAuthModule,
37 | ],
38 | bootstrap: [IonicApp],
39 | entryComponents: [
40 | MyApp,
41 | LoginPage,
42 | RegisterPage,
43 | UserPage
44 | ],
45 | providers: [
46 | StatusBar,
47 | SplashScreen,
48 | Facebook,
49 | GooglePlus,
50 | AuthService,
51 | TwitterConnect,
52 | UserService,
53 | {provide: ErrorHandler, useClass: IonicErrorHandler}
54 | ]
55 | })
56 | export class AppModule {}
57 |
--------------------------------------------------------------------------------
/ionic-v3/src/app/app.scss:
--------------------------------------------------------------------------------
1 | // http://ionicframework.com/docs/theming/
2 |
3 |
4 | // App Global Sass
5 | // --------------------------------------------------
6 | // Put style rules here that you want to apply globally. These
7 | // styles are for the entire app and not just one component.
8 | // Additionally, this file can be also used as an entry point
9 | // to import other Sass files to be included in the output CSS.
10 | //
11 | // Shared Sass variables, which can be used to adjust Ionic's
12 | // default Sass variables, belong in "theme/variables.scss".
13 | //
14 | // To declare rules for a specific mode, create a child rule
15 | // for the .md, .ios, or .wp mode classes. The mode class is
16 | // automatically applied to the element in the app.
17 |
--------------------------------------------------------------------------------
/ionic-v3/src/app/main.ts:
--------------------------------------------------------------------------------
1 | import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
2 |
3 | import { AppModule } from './app.module';
4 |
5 | platformBrowserDynamic().bootstrapModule(AppModule);
6 |
--------------------------------------------------------------------------------
/ionic-v3/src/assets/icon/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ionicthemes/ionic5-firebase-authentication/c599afaddf333e94b7c7bfc4c906b216c47bb252/ionic-v3/src/assets/icon/favicon.ico
--------------------------------------------------------------------------------
/ionic-v3/src/assets/imgs/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ionicthemes/ionic5-firebase-authentication/c599afaddf333e94b7c7bfc4c906b216c47bb252/ionic-v3/src/assets/imgs/logo.png
--------------------------------------------------------------------------------
/ionic-v3/src/environment/environment.ts:
--------------------------------------------------------------------------------
1 | export const environment = {
2 | production: false,
3 | // fbAppId: 186848361921511,
4 | googleWebClientId: '401245627689-ke4oci7bc8440anmpo4dms1od5keoome.apps.googleusercontent.com',
5 | firebase: {
6 | apiKey: "AIzaSyATBlD3709OkzGzNq5_a1Db2jk8-SBPDlg",
7 | authDomain: "thinking-return-94920.firebaseapp.com",
8 | databaseURL: "https://thinking-return-94920.firebaseio.com",
9 | projectId: "thinking-return-94920",
10 | storageBucket: "thinking-return-94920.appspot.com",
11 | messagingSenderId: "401245627689"
12 | }
13 | };
14 |
--------------------------------------------------------------------------------
/ionic-v3/src/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Ionic App
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
--------------------------------------------------------------------------------
/ionic-v3/src/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "Ionic",
3 | "short_name": "Ionic",
4 | "start_url": "index.html",
5 | "display": "standalone",
6 | "icons": [{
7 | "src": "assets/imgs/logo.png",
8 | "sizes": "512x512",
9 | "type": "image/png"
10 | }],
11 | "background_color": "#4e8ef7",
12 | "theme_color": "#4e8ef7"
13 | }
--------------------------------------------------------------------------------
/ionic-v3/src/pages/core/auth.service.ts:
--------------------------------------------------------------------------------
1 | import { Injectable } from "@angular/core";
2 | import { Platform } from 'ionic-angular';
3 | import 'rxjs/add/operator/toPromise';
4 | import { AngularFireAuth } from 'angularfire2/auth';
5 | import * as firebase from 'firebase/app';
6 | import { Facebook } from '@ionic-native/facebook';
7 | import { GooglePlus } from '@ionic-native/google-plus';
8 | import { TwitterConnect } from '@ionic-native/twitter-connect';
9 | import { FirebaseUserModel } from './user.model';
10 | import { environment } from '../../environment/environment';
11 |
12 |
13 | @Injectable()
14 | export class AuthService {
15 |
16 | constructor(
17 | public afAuth: AngularFireAuth,
18 | public fb: Facebook,
19 | public googlePlus: GooglePlus,
20 | public tw : TwitterConnect,
21 | public platform: Platform
22 | ){}
23 |
24 | doRegister(value){
25 | return new Promise((resolve, reject) => {
26 | firebase.auth().createUserWithEmailAndPassword(value.email, value.password)
27 | .then(res => {
28 | resolve(res);
29 | }, err => reject(err))
30 | })
31 | }
32 |
33 | doLogin(value){
34 | return new Promise((resolve, reject) => {
35 | firebase.auth().signInWithEmailAndPassword(value.email, value.password)
36 | .then(res => {
37 | resolve(res);
38 | }, err => reject(err))
39 | })
40 | }
41 |
42 | doLogout(){
43 | return new Promise((resolve, reject) => {
44 | if(firebase.auth().currentUser){
45 | this.afAuth.auth.signOut()
46 | resolve();
47 | }
48 | else {
49 | reject();
50 | }
51 | });
52 | }
53 |
54 | doGoogleLogin(){
55 | return new Promise((resolve, reject) => {
56 | if (this.platform.is('cordova')) {
57 | this.googlePlus.login({
58 | 'scopes': '', // optional, space-separated list of scopes, If not included or empty, defaults to `profile` and `email`.
59 | 'webClientId': environment.googleWebClientId, // optional clientId of your Web application from Credentials settings of your project - On Android, this MUST be included to get an idToken. On iOS, it is not required.
60 | 'offline': true
61 | }).then((response) => {
62 | const googleCredential = firebase.auth.GoogleAuthProvider.credential(response.idToken);
63 | firebase.auth().signInWithCredential(googleCredential)
64 | .then((user) => {
65 | resolve();
66 | });
67 | },(err) => {
68 | reject(err);
69 | });
70 | }
71 | else{
72 | this.afAuth.auth
73 | .signInWithPopup(new firebase.auth.GoogleAuthProvider())
74 | .then((user) => {
75 | resolve()
76 | },(err) => {
77 | reject(err);
78 | })
79 | }
80 | })
81 | }
82 |
83 | doFacebookLogin(){
84 | return new Promise((resolve, reject) => {
85 | if (this.platform.is('cordova')) {
86 | //["public_profile"] is the array of permissions, you can add more if you need
87 | this.fb.login(["public_profile"])
88 | .then((response) => {
89 | const facebookCredential = firebase.auth.FacebookAuthProvider.credential(response.authResponse.accessToken);
90 | firebase.auth().signInWithCredential(facebookCredential)
91 | .then(user => resolve());
92 | }, err => reject(err)
93 | );
94 | }
95 | else {
96 | this.afAuth.auth
97 | .signInWithPopup(new firebase.auth.FacebookAuthProvider())
98 | .then(result => {
99 | //Default facebook img is too small and we need a bigger image
100 | var bigImgUrl = "https://graph.facebook.com/" + result.additionalUserInfo.profile + "/picture?height=500";
101 | // update profile to save the big fb profile img.
102 | firebase.auth().currentUser.updateProfile({
103 | displayName: result.user.displayName,
104 | photoURL: bigImgUrl
105 | }).then(res => resolve()
106 | ,(err) => {
107 | reject(err);
108 | });
109 | },(err) => {
110 | reject(err);
111 | })
112 | }
113 | })
114 | }
115 |
116 | doTwitterLogin(){
117 | return new Promise((resolve, reject) => {
118 | // if we are in a mobile device we use the twitter native plugin
119 |
120 | if (this.platform.is('cordova')) {
121 | this.tw.login()
122 | .then((response) => {
123 | const twitterCredential = firebase.auth.TwitterAuthProvider.credential(response.token, response.secret);
124 | firebase.auth().signInWithCredential(twitterCredential)
125 | .then(
126 | user => resolve(),
127 | error => reject(error)
128 | );
129 | },
130 | err => {
131 | console.log(err);
132 | reject(err);
133 | }
134 | );
135 | }
136 | else {
137 | this.afAuth.auth
138 | .signInWithPopup(new firebase.auth.TwitterAuthProvider())
139 | .then(result => {
140 | //Default twitter img is just 48x48px and we need a bigger image https://developer.twitter.com/en/docs/accounts-and-users/user-profile-images-and-banners
141 | var bigImgUrl = (result.user.photoURL).replace('_normal', '_400x400');
142 |
143 | // update profile to save the big tw profile img.
144 | firebase.auth().currentUser.updateProfile({
145 | displayName: result.user.displayName,
146 | photoURL: bigImgUrl
147 | }).then(res => resolve(),(err) => {
148 | reject(err);
149 | });
150 | },(err) => {
151 | reject(err);
152 | })
153 | }
154 | })
155 | }
156 | }
157 |
--------------------------------------------------------------------------------
/ionic-v3/src/pages/core/user.model.ts:
--------------------------------------------------------------------------------
1 | export class FirebaseUserModel {
2 | image: string;
3 | name: string;
4 | provider: string;
5 |
6 | constructor(){
7 | this.image = "";
8 | this.name = "";
9 | this.provider = "";
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/ionic-v3/src/pages/core/user.service.ts:
--------------------------------------------------------------------------------
1 | import { Injectable } from "@angular/core";
2 | import 'rxjs/add/operator/toPromise';
3 | import * as firebase from 'firebase/app';
4 | import { FirebaseUserModel } from './user.model';
5 |
6 | @Injectable()
7 | export class UserService {
8 |
9 | constructor(){}
10 |
11 |
12 | getCurrentUser(){
13 | return new Promise((resolve, reject) => {
14 | firebase.auth().onAuthStateChanged(function(user){
15 | let userModel = new FirebaseUserModel();
16 | if (user) {
17 | if(user.providerData[0].providerId == 'password'){
18 | //use a default image
19 | userModel.image = 'http://dsi-vd.github.io/patternlab-vd/images/fpo_avatar.png';
20 | userModel.name = user.displayName;
21 | userModel.provider = user.providerData[0].providerId;
22 | return resolve(userModel);
23 | }
24 | else{
25 | userModel.image = user.photoURL;
26 | userModel.name = user.displayName;
27 | userModel.provider = user.providerData[0].providerId;
28 | return resolve(userModel);
29 | }
30 | } else {
31 | reject('No user logged in');
32 | }
33 | })
34 | })
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/ionic-v3/src/pages/login/login.html:
--------------------------------------------------------------------------------
1 |
2 |
3 | Login
4 |
5 |
6 |
7 |
8 |
32 |
33 |
34 |
35 |
36 |
--------------------------------------------------------------------------------
/ionic-v3/src/pages/login/login.scss:
--------------------------------------------------------------------------------
1 | page-login {
2 | ion-header {
3 | @include header-styles(color($colors, header, base), color($colors, header, contrast));
4 | }
5 |
6 | .error-message{
7 | color: red;
8 | }
9 | .submit-button
10 | {
11 | margin: 0px;
12 | margin-top: 20px;
13 | @include call-to-action-button-styles(color($colors, button, base), color($colors, button, contrast));
14 | }
15 |
16 | .twitter-button{
17 | margin: 0px;
18 | margin-top: 20px;
19 | @include call-to-action-button-styles(color($colors, twitter, base), color($colors, twitter, contrast));
20 | }
21 | .facebook-button
22 | {
23 | margin: 0px;
24 | @include call-to-action-button-styles(color($colors, facebook, base), color($colors, facebook, contrast));
25 | }
26 |
27 | .google-button
28 | {
29 | margin: 0px;
30 | margin-top: 20px;
31 | @include call-to-action-button-styles(color($colors, google, base), color($colors, google, contrast));
32 | }
33 |
34 | }
35 |
--------------------------------------------------------------------------------
/ionic-v3/src/pages/login/login.ts:
--------------------------------------------------------------------------------
1 | import { Component } from '@angular/core';
2 | import { NavController } from 'ionic-angular';
3 |
4 | import { FormBuilder, FormGroup, FormControl } from '@angular/forms';
5 |
6 | import { RegisterPage } from '../register/register';
7 | import { UserPage } from '../user/user';
8 | import { AuthService } from '../core/auth.service';
9 |
10 |
11 | @Component({
12 | selector: 'page-login',
13 | templateUrl: 'login.html'
14 | })
15 | export class LoginPage {
16 |
17 | loginForm: FormGroup;
18 | errorMessage: string = '';
19 |
20 | constructor(
21 | public navCtrl: NavController,
22 | public authService: AuthService,
23 | public formBuilder: FormBuilder
24 | ) {}
25 |
26 | ionViewWillLoad(){
27 | this.loginForm = this.formBuilder.group({
28 | email: new FormControl(),
29 | password: new FormControl(),
30 | });
31 | }
32 |
33 | tryLogin(value){
34 | this.authService.doLogin(value)
35 | .then(res => {
36 | console.log(res);
37 | this.navCtrl.push(UserPage);
38 | }, err => {
39 | console.log(err);
40 | this.errorMessage = err.message;
41 | })
42 | }
43 |
44 | tryFacebookLogin(){
45 | this.authService.doFacebookLogin()
46 | .then((res) => {
47 | this.navCtrl.push(UserPage);
48 | }, (err) => {
49 | this.errorMessage = err.message;
50 | });
51 | }
52 |
53 | tryGoogleLogin(){
54 | this.authService.doGoogleLogin()
55 | .then((res) => {
56 | this.navCtrl.push(UserPage);
57 | }, (err) => {
58 | this.errorMessage = err.message;
59 | });
60 | }
61 |
62 | tryTwitterLogin(){
63 | this.authService.doTwitterLogin()
64 | .then((res) => {
65 | this.navCtrl.push(UserPage);
66 | }, (err) => {
67 | this.errorMessage = err.message;
68 | });
69 | }
70 |
71 | goRegisterPage(){
72 | this.navCtrl.push(RegisterPage);
73 | }
74 |
75 | }
76 |
--------------------------------------------------------------------------------
/ionic-v3/src/pages/register/register.html:
--------------------------------------------------------------------------------
1 |
2 |
3 | Register
4 |
5 |
6 |
7 |
8 |
28 |
29 |
30 |
31 |
32 |
--------------------------------------------------------------------------------
/ionic-v3/src/pages/register/register.scss:
--------------------------------------------------------------------------------
1 | page-register {
2 | ion-header {
3 | @include header-styles(color($colors, header, base), color($colors, header, contrast));
4 | }
5 |
6 | .error-message
7 | {
8 | color: red;
9 | }
10 |
11 | .success-message{
12 | color: green;
13 | }
14 |
15 | .submit-button
16 | {
17 | margin: 0px;
18 | margin-top: 20px;
19 | @include call-to-action-button-styles(color($colors, button, base), color($colors, button, contrast));
20 | }
21 |
22 | .twitter-button{
23 | margin: 0px;
24 | margin-top: 20px;
25 | @include call-to-action-button-styles(color($colors, twitter, base), color($colors, twitter, contrast));
26 | }
27 | .facebook-button
28 | {
29 | margin: 0px;
30 | @include call-to-action-button-styles(color($colors, facebook, base), color($colors, facebook, contrast));
31 | }
32 |
33 | .google-button
34 | {
35 | margin: 0px;
36 | margin-top: 20px;
37 | @include call-to-action-button-styles(color($colors, google, base), color($colors, google, contrast));
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/ionic-v3/src/pages/register/register.ts:
--------------------------------------------------------------------------------
1 | import { Component } from '@angular/core';
2 | import { NavController } from 'ionic-angular';
3 |
4 | import { FormBuilder, FormGroup, FormControl } from '@angular/forms';
5 |
6 | import { AuthService } from '../core/auth.service';
7 |
8 | import { UserPage } from '../user/user';
9 |
10 |
11 |
12 | @Component({
13 | selector: 'page-register',
14 | templateUrl: 'register.html'
15 | })
16 | export class RegisterPage {
17 |
18 | registerForm: FormGroup;
19 | errorMessage: string = '';
20 | successMessage: string = '';
21 |
22 | constructor(
23 | public navCtrl: NavController,
24 | public authService: AuthService,
25 | public formBuilder: FormBuilder
26 | ) {}
27 |
28 | ionViewWillLoad(){
29 | this.registerForm = this.formBuilder.group({
30 | email: new FormControl(),
31 | password: new FormControl()
32 | });
33 | }
34 |
35 | tryRegister(value){
36 | this.authService.doRegister(value)
37 | .then(res => {
38 | this.errorMessage = "";
39 | this.successMessage = "Your account has been created. Please log in now.";
40 | }, err => {
41 | this.errorMessage = err.message;
42 | this.successMessage = "";
43 | })
44 | }
45 |
46 | tryFacebookLogin(){
47 | this.authService.doFacebookLogin()
48 | .then((res) => {
49 | this.navCtrl.push(UserPage);
50 | }, (err) => {
51 | this.errorMessage = err.message;
52 | });
53 | }
54 |
55 | tryGoogleLogin(){
56 | this.authService.doGoogleLogin()
57 | .then((res) => {
58 | this.navCtrl.push(UserPage);
59 | }, (err) => {
60 | this.errorMessage = err.message;
61 | });
62 | }
63 |
64 | tryTwitterLogin(){
65 | this.authService.doTwitterLogin()
66 | .then((res) => {
67 | this.navCtrl.push(UserPage);
68 | }, (err) => {
69 | this.errorMessage = err.message;
70 | });
71 | }
72 |
73 | goLoginPage(){
74 | this.navCtrl.pop();
75 | }
76 |
77 | }
78 |
--------------------------------------------------------------------------------
/ionic-v3/src/pages/user/user.html:
--------------------------------------------------------------------------------
1 |
2 |
3 | User
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 | {{user.name}}
12 |
13 |
14 | This is an example app of authentication using Firebase in an Ionic 3 app.
15 |
16 |
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/ionic-v3/src/pages/user/user.scss:
--------------------------------------------------------------------------------
1 | page-user {
2 | ion-header {
3 | @include header-styles(color($colors, header, base), color($colors, header, contrast));
4 | }
5 | }
6 |
--------------------------------------------------------------------------------
/ionic-v3/src/pages/user/user.ts:
--------------------------------------------------------------------------------
1 | import { Component } from '@angular/core';
2 | import { NavController } from 'ionic-angular';
3 | import { UserService } from '../core/user.service';
4 | import { AuthService } from '../core/auth.service';
5 | import { FirebaseUserModel } from '../core/user.model';
6 |
7 | @Component({
8 | selector: 'page-user',
9 | templateUrl: 'user.html'
10 | })
11 |
12 | export class UserPage{
13 |
14 | user: FirebaseUserModel = new FirebaseUserModel();
15 |
16 | constructor(
17 | public navCtrl: NavController,
18 | public userService: UserService,
19 | public authService: AuthService
20 | ) {}
21 |
22 | ionViewWillLoad(){
23 | this.userService.getCurrentUser()
24 | .then(user => {
25 | this.user = user;
26 | }, err => console.log(err))
27 | }
28 |
29 |
30 | logout(){
31 | this.authService.doLogout()
32 | .then((res) => {
33 | this.navCtrl.pop();
34 | }, (error) => {
35 | console.log("Logout error", error);
36 | });
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/ionic-v3/src/service-worker.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Check out https://googlechromelabs.github.io/sw-toolbox/ for
3 | * more info on how to use sw-toolbox to custom configure your service worker.
4 | */
5 |
6 |
7 | 'use strict';
8 | importScripts('./build/sw-toolbox.js');
9 |
10 | self.toolbox.options.cache = {
11 | name: 'ionic-cache'
12 | };
13 |
14 | // pre-cache our key assets
15 | self.toolbox.precache(
16 | [
17 | './build/main.js',
18 | './build/vendor.js',
19 | './build/main.css',
20 | './build/polyfills.js',
21 | 'index.html',
22 | 'manifest.json'
23 | ]
24 | );
25 |
26 | // dynamically cache any other local assets
27 | self.toolbox.router.any('/*', self.toolbox.fastest);
28 |
29 | // for any other requests go to the network, cache,
30 | // and then only use that cached resource if your user goes offline
31 | self.toolbox.router.default = self.toolbox.networkFirst;
32 |
--------------------------------------------------------------------------------
/ionic-v3/src/theme/commons.scss:
--------------------------------------------------------------------------------
1 | @mixin call-to-action-button-styles($background, $color){
2 | border-radius: 6px;
3 | color: $color;
4 | background-color: $background;
5 | font-size: 1.6rem;
6 | font-weight: 500;
7 | }
8 |
9 | @mixin header-styles($background, $color){
10 | .toolbar-background
11 | {
12 | border: none !important;
13 | background-color: $background;
14 | }
15 |
16 | .toolbar-title,
17 | .back-button,
18 | .bar-button
19 | {
20 | color: $color;
21 | }
22 | }
23 |
24 | ion-header {
25 | @include header-styles(color($colors, header, base), color($colors, header, contrast));
26 | }
27 |
--------------------------------------------------------------------------------
/ionic-v3/src/theme/variables.scss:
--------------------------------------------------------------------------------
1 | // Ionic Variables and Theming. For more info, please see:
2 | // http://ionicframework.com/docs/theming/
3 |
4 | // Font path is used to include ionicons,
5 | // roboto, and noto sans fonts
6 | $font-path: "../assets/fonts";
7 |
8 |
9 | // The app direction is used to include
10 | // rtl styles in your app. For more info, please see:
11 | // http://ionicframework.com/docs/theming/rtl-support/
12 | $app-direction: ltr;
13 |
14 |
15 | @import "ionic.globals";
16 |
17 |
18 | // Shared Variables
19 | // --------------------------------------------------
20 | // To customize the look and feel of this app, you can override
21 | // the Sass variables found in Ionic's source scss files.
22 | // To view all the possible Ionic variables, see:
23 | // http://ionicframework.com/docs/theming/overriding-ionic-variables/
24 | $white: #FFFFFF;
25 | $theme-color-1: #00e9d5;
26 | $header-color: #488aff;
27 |
28 |
29 | // Named Color Variables
30 | // --------------------------------------------------
31 | // Named colors makes it easy to reuse colors on various components.
32 | // It's highly recommended to change the default colors
33 | // to match your app's branding. Ionic uses a Sass map of
34 | // colors so you can add, rename and remove colors as needed.
35 | // The "primary" color is the only required color in the map.
36 |
37 | $colors: (
38 | primary: #488aff,
39 | secondary: #32db64,
40 | danger: #f53d3d,
41 | light: #f4f4f4,
42 | dark: #222,
43 | twitter:(
44 | base: #00aced,
45 | contrast: $white
46 | ),
47 | facebook:(
48 | base: #3b5998,
49 | contrast: $white
50 | ),
51 | google:(
52 | base: #cc181e,
53 | contrast: $white
54 | ),
55 | button:(
56 | base: $theme-color-1,
57 | contrast: $white
58 | ),
59 | header:(
60 | base: $header-color,
61 | contrast: $white
62 | )
63 | );
64 |
65 |
66 | // App iOS Variables
67 | // --------------------------------------------------
68 | // iOS only Sass variables can go here
69 |
70 |
71 |
72 |
73 | // App Material Design Variables
74 | // --------------------------------------------------
75 | // Material Design only Sass variables can go here
76 |
77 |
78 |
79 |
80 | // App Windows Variables
81 | // --------------------------------------------------
82 | // Windows only Sass variables can go here
83 |
84 |
85 |
86 |
87 | // App Theme
88 | // --------------------------------------------------
89 | // Ionic apps can have different themes applied, which can
90 | // then be future customized. This import comes last
91 | // so that the above variables are used and Ionic's
92 | // default are overridden.
93 |
94 | @import "ionic.theme.default";
95 |
96 | @import "./commons";
97 |
98 | // Ionicons
99 | // --------------------------------------------------
100 | // The premium icon font for Ionic. For more info, please see:
101 | // http://ionicframework.com/docs/ionicons/
102 |
103 | @import "ionic.ionicons";
104 |
105 |
106 | // Fonts
107 | // --------------------------------------------------
108 |
109 | @import "roboto";
110 | @import "noto-sans";
111 |
--------------------------------------------------------------------------------
/ionic-v3/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "allowSyntheticDefaultImports": true,
4 | "declaration": false,
5 | "emitDecoratorMetadata": true,
6 | "experimentalDecorators": true,
7 | "lib": [
8 | "dom",
9 | "es2015"
10 | ],
11 | "module": "es2015",
12 | "moduleResolution": "node",
13 | "sourceMap": true,
14 | "target": "es5"
15 | },
16 | "include": [
17 | "src/**/*.ts"
18 | ],
19 | "exclude": [
20 | "node_modules",
21 | "src/**/*.spec.ts",
22 | "src/**/__tests__/*.ts"
23 | ],
24 | "compileOnSave": false,
25 | "atom": {
26 | "rewriteTsconfig": false
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/ionic-v3/tslint.json:
--------------------------------------------------------------------------------
1 | {
2 | "rules": {
3 | "no-duplicate-variable": true,
4 | "no-unused-variable": [
5 | true
6 | ]
7 | },
8 | "rulesDirectory": [
9 | "node_modules/tslint-eslint-rules/dist/rules"
10 | ]
11 | }
12 |
--------------------------------------------------------------------------------
/ionic.config.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "ionic5-firebase-authentication",
3 | "integrations": {
4 | "capacitor": {}
5 | },
6 | "type": "angular"
7 | }
8 |
--------------------------------------------------------------------------------
/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', 'text-summary'],
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 | };
32 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "ionic5-firebase-authentication",
3 | "version": "1.0.0",
4 | "author": "IonicThemes Team",
5 | "homepage": "https://ionicthemes.com/",
6 | "scripts": {
7 | "ng": "ng",
8 | "start": "ng serve",
9 | "build": "ng build",
10 | "test": "ng test",
11 | "lint": "ng lint",
12 | "e2e": "ng e2e"
13 | },
14 | "private": true,
15 | "dependencies": {
16 | "@angular/common": "~10.2.0",
17 | "@angular/core": "~10.2.0",
18 | "@angular/fire": "^6.0.3",
19 | "@angular/forms": "~10.2.0",
20 | "@angular/platform-browser": "~10.2.0",
21 | "@angular/platform-browser-dynamic": "~10.2.0",
22 | "@angular/router": "~10.2.0",
23 | "@capacitor/core": "^2.4.2",
24 | "@ionic-native/core": "^5.0.7",
25 | "@ionic-native/splash-screen": "^5.0.0",
26 | "@ionic-native/status-bar": "^5.0.0",
27 | "@ionic/angular": "^5.4.1",
28 | "core-js": "^2.5.4",
29 | "firebase": "^7.24.0",
30 | "rxjs": "~6.6.3",
31 | "tslib": "^1.9.0",
32 | "zone.js": "~0.10.3"
33 | },
34 | "devDependencies": {
35 | "@angular-devkit/architect": "^0.1002.0",
36 | "@angular-devkit/build-angular": "^0.1002.0",
37 | "@angular-devkit/core": "^10.2.0",
38 | "@angular-devkit/schematics": "^10.2.0",
39 | "@angular/cli": "~10.2.0",
40 | "@angular/compiler": "~10.2.0",
41 | "@angular/compiler-cli": "~10.2.0",
42 | "@angular/language-service": "~10.2.0",
43 | "@capacitor/cli": "^2.4.2",
44 | "@ionic/angular-toolkit": "^2.3.3",
45 | "@types/jasmine": "~3.5.0",
46 | "@types/jasminewd2": "~2.0.3",
47 | "@types/node": "^12.11.1",
48 | "codelyzer": "^5.1.2",
49 | "jasmine-core": "~3.5.0",
50 | "jasmine-spec-reporter": "~4.2.1",
51 | "karma": "~5.0.0",
52 | "karma-chrome-launcher": "~3.1.0",
53 | "karma-coverage-istanbul-reporter": "~2.1.0",
54 | "karma-jasmine": "~3.0.1",
55 | "karma-jasmine-html-reporter": "^1.4.2",
56 | "protractor": "~5.4.3",
57 | "ts-node": "~8.3.0",
58 | "tslint": "~6.1.0",
59 | "typescript": "~4.0.3"
60 | },
61 | "description": "An Ionic project with Firebase Authentication"
62 | }
63 |
--------------------------------------------------------------------------------
/src/app/app-routing.module.ts:
--------------------------------------------------------------------------------
1 | import { NgModule } from '@angular/core';
2 | import { PreloadAllModules, RouterModule, Routes } from '@angular/router';
3 |
4 | const routes: Routes = [
5 | {
6 | path: 'sign-in',
7 | loadChildren: () => import('./sign-in/sign-in.module').then( m => m.SignInPageModule)
8 | },
9 | {
10 | path: 'sign-up',
11 | loadChildren: () => import('./sign-up/sign-up.module').then( m => m.SignUpPageModule)
12 | },
13 | {
14 | path: 'profile',
15 | loadChildren: () => import('./profile/profile.module').then( m => m.ProfilePageModule)
16 | },
17 | {
18 | path: '',
19 | redirectTo: 'sign-in',
20 | pathMatch: 'full'
21 | },
22 | ];
23 |
24 | @NgModule({
25 | imports: [
26 | RouterModule.forRoot(routes, { preloadingStrategy: PreloadAllModules })
27 | ],
28 | exports: [RouterModule]
29 | })
30 | export class AppRoutingModule { }
31 |
--------------------------------------------------------------------------------
/src/app/app.component.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/src/app/app.component.spec.ts:
--------------------------------------------------------------------------------
1 | import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
2 | import { TestBed, async } from '@angular/core/testing';
3 |
4 | import { Platform } from '@ionic/angular';
5 | import { SplashScreen } from '@ionic-native/splash-screen/ngx';
6 | import { StatusBar } from '@ionic-native/status-bar/ngx';
7 |
8 | import { AppComponent } from './app.component';
9 |
10 | describe('AppComponent', () => {
11 |
12 | let statusBarSpy, splashScreenSpy, platformReadySpy, platformSpy;
13 |
14 | beforeEach(async(() => {
15 | statusBarSpy = jasmine.createSpyObj('StatusBar', ['styleDefault']);
16 | splashScreenSpy = jasmine.createSpyObj('SplashScreen', ['hide']);
17 | platformReadySpy = Promise.resolve();
18 | platformSpy = jasmine.createSpyObj('Platform', { ready: platformReadySpy });
19 |
20 | TestBed.configureTestingModule({
21 | declarations: [AppComponent],
22 | schemas: [CUSTOM_ELEMENTS_SCHEMA],
23 | providers: [
24 | { provide: StatusBar, useValue: statusBarSpy },
25 | { provide: SplashScreen, useValue: splashScreenSpy },
26 | { provide: Platform, useValue: platformSpy },
27 | ],
28 | }).compileComponents();
29 | }));
30 |
31 | it('should create the app', () => {
32 | const fixture = TestBed.createComponent(AppComponent);
33 | const app = fixture.debugElement.componentInstance;
34 | expect(app).toBeTruthy();
35 | });
36 |
37 | it('should initialize the app', async () => {
38 | TestBed.createComponent(AppComponent);
39 | expect(platformSpy.ready).toHaveBeenCalled();
40 | await platformReadySpy;
41 | expect(statusBarSpy.styleDefault).toHaveBeenCalled();
42 | expect(splashScreenSpy.hide).toHaveBeenCalled();
43 | });
44 |
45 | // TODO: add more tests!
46 |
47 | });
48 |
--------------------------------------------------------------------------------
/src/app/app.component.ts:
--------------------------------------------------------------------------------
1 | import { Component } from '@angular/core';
2 |
3 | import { Platform } from '@ionic/angular';
4 | import { SplashScreen } from '@ionic-native/splash-screen/ngx';
5 | import { StatusBar } from '@ionic-native/status-bar/ngx';
6 |
7 | @Component({
8 | selector: 'app-root',
9 | templateUrl: 'app.component.html'
10 | })
11 | export class AppComponent {
12 | constructor(
13 | private platform: Platform,
14 | private splashScreen: SplashScreen,
15 | private statusBar: StatusBar
16 | ) {
17 | this.initializeApp();
18 | }
19 |
20 | initializeApp() {
21 | this.platform.ready().then(() => {
22 | this.statusBar.styleDefault();
23 | this.splashScreen.hide();
24 | });
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/src/app/app.module.ts:
--------------------------------------------------------------------------------
1 | import { NgModule } from '@angular/core';
2 | import { BrowserModule } from '@angular/platform-browser';
3 | import { RouteReuseStrategy } from '@angular/router';
4 |
5 | import { IonicModule, IonicRouteStrategy } from '@ionic/angular';
6 | import { SplashScreen } from '@ionic-native/splash-screen/ngx';
7 | import { StatusBar } from '@ionic-native/status-bar/ngx';
8 |
9 | import { AppComponent } from './app.component';
10 | import { AppRoutingModule } from './app-routing.module';
11 |
12 | import { AngularFireModule } from '@angular/fire';
13 | import { AngularFireAuthModule } from '@angular/fire/auth';
14 | import { environment } from '../environments/environment';
15 | import { FirebaseAuthService } from './firebase-auth.service';
16 |
17 | @NgModule({
18 | declarations: [AppComponent],
19 | imports: [
20 | BrowserModule,
21 | IonicModule.forRoot(),
22 | AppRoutingModule,
23 | AngularFireModule.initializeApp(environment.firebase),
24 | AngularFireAuthModule
25 | ],
26 | providers: [
27 | StatusBar,
28 | SplashScreen,
29 | FirebaseAuthService,
30 | { provide: RouteReuseStrategy, useClass: IonicRouteStrategy }
31 | ],
32 | bootstrap: [AppComponent]
33 | })
34 | export class AppModule {}
35 |
--------------------------------------------------------------------------------
/src/app/firebase-auth.service.ts:
--------------------------------------------------------------------------------
1 | import { Injectable } from '@angular/core';
2 | import { AngularFireAuth } from '@angular/fire/auth';
3 | import { Observable, Subject, from } from 'rxjs';
4 | import { Platform } from '@ionic/angular';
5 | import { User, auth } from 'firebase/app';
6 | import { ProfileModel } from './profile/profile.model';
7 | import { filter, map, take } from 'rxjs/operators';
8 |
9 | @Injectable()
10 | export class FirebaseAuthService {
11 |
12 | currentUser: User;
13 | userProviderAdditionalInfo: any;
14 | redirectResult: Subject = new Subject();
15 |
16 | constructor(
17 | public angularFireAuth: AngularFireAuth,
18 | public platform: Platform
19 | ) {
20 | this.angularFireAuth.onAuthStateChanged((user) => {
21 | if (user) {
22 | // User is signed in.
23 | this.currentUser = user;
24 | } else {
25 | // No user is signed in.
26 | this.currentUser = null;
27 | }
28 | });
29 |
30 | // when using signInWithRedirect, this listens for the redirect results
31 | this.angularFireAuth.getRedirectResult()
32 | .then((result) => {
33 | // result.credential.accessToken gives you the Provider Access Token. You can use it to access the Provider API.
34 | if (result.user) {
35 | this.setProviderAdditionalInfo(result.additionalUserInfo.profile);
36 | this.currentUser = result.user;
37 | this.redirectResult.next(result);
38 | }
39 | }, (error) => {
40 | this.redirectResult.next({error: error.code});
41 | });
42 | }
43 |
44 | getRedirectResult(): Observable {
45 | return this.redirectResult.asObservable();
46 | }
47 |
48 | setProviderAdditionalInfo(additionalInfo: any) {
49 | this.userProviderAdditionalInfo = {...additionalInfo};
50 | }
51 |
52 | public getProfileDataSource() {
53 | return this.angularFireAuth.user
54 | .pipe(
55 | filter((user: User) => user != null),
56 | map((user: User) => {
57 | return this.getProfileData();
58 | }),
59 | take(1) // this.angularFireAuth.user never completes so we use take(1) in order to complete after the first value is emitted
60 | );
61 | }
62 |
63 | public getProfileData() {
64 | const userModel = new ProfileModel();
65 | let providerData : any = this.currentUser.providerData[0];
66 |
67 | if (this.userProviderAdditionalInfo) {
68 | providerData = {...providerData, ...this.userProviderAdditionalInfo};
69 | }
70 |
71 | // Default imgs are too small and our app needs a bigger image
72 | switch (providerData.providerId) {
73 | case 'facebook.com':
74 | userModel.image = providerData.photoURL + '?height=400';
75 | break;
76 | case 'password':
77 | userModel.image = 'https://s3-us-west-2.amazonaws.com/ionicthemes/otros/avatar-placeholder.png';
78 | break;
79 | case 'twitter.com':
80 | userModel.image = providerData.photoURL.replace('_normal', '_400x400');
81 | break;
82 | case 'google.com':
83 | userModel.image = providerData.photoURL.split('=')[0];
84 | break;
85 | default:
86 | userModel.image = providerData.photoURL;
87 | }
88 | userModel.name = providerData.name || providerData.displayName || 'What\'s your name?';
89 | userModel.role = 'How would you describe yourself?';
90 | userModel.description = providerData.description || 'Anything else you would like to share with the world?';
91 | userModel.phoneNumber = providerData.phoneNumber || 'Is there a number where I can reach you?';
92 | userModel.email = providerData.email || 'Where can I send you emails?';
93 | userModel.provider = (providerData.providerId !== 'password') ? providerData.providerId : 'Credentials';
94 |
95 | return userModel;
96 | }
97 |
98 | signOut(): Observable {
99 | return from(this.angularFireAuth.signOut());
100 | }
101 |
102 | signInWithEmail(email: string, password: string): Promise {
103 | return this.angularFireAuth.signInWithEmailAndPassword(email, password);
104 | }
105 |
106 | signUpWithEmail(email: string, password: string): Promise {
107 | return this.angularFireAuth.createUserWithEmailAndPassword(email, password);
108 | }
109 |
110 | socialSignIn(providerName: string, scopes?: Array): Promise {
111 | const provider = new auth.OAuthProvider(providerName);
112 |
113 | // add any permission scope you need
114 | if (scopes) {
115 | scopes.forEach(scope => {
116 | provider.addScope(scope);
117 | });
118 | }
119 |
120 | if (this.platform.is('desktop')) {
121 | return this.angularFireAuth.signInWithPopup(provider);
122 | } else {
123 | // web but not desktop, for example mobile PWA
124 | return this.angularFireAuth.signInWithRedirect(provider);
125 | }
126 | }
127 |
128 | signInWithFacebook() {
129 | const provider = new auth.FacebookAuthProvider();
130 | // const scopes = ['user_birthday'];
131 | return this.socialSignIn(provider.providerId);
132 | }
133 |
134 | signInWithGoogle() {
135 | const provider = new auth.GoogleAuthProvider();
136 | const scopes = ['profile', 'email'];
137 | return this.socialSignIn(provider.providerId, scopes);
138 | }
139 |
140 | signInWithTwitter() {
141 | const provider = new auth.TwitterAuthProvider();
142 | return this.socialSignIn(provider.providerId);
143 | }
144 | }
145 |
--------------------------------------------------------------------------------
/src/app/profile/profile.model.ts:
--------------------------------------------------------------------------------
1 | export class ProfileModel {
2 | image: string;
3 | name: string;
4 | role: string;
5 | description: string;
6 | email: string;
7 | provider: string;
8 | phoneNumber: string;
9 | }
10 |
--------------------------------------------------------------------------------
/src/app/profile/profile.module.ts:
--------------------------------------------------------------------------------
1 | import { NgModule } from '@angular/core';
2 | import { CommonModule } from '@angular/common';
3 | import { FormsModule } from '@angular/forms';
4 |
5 | import { IonicModule } from '@ionic/angular';
6 |
7 | import { ProfilePage } from './profile.page';
8 | import { RouterModule, Routes } from '@angular/router';
9 | import { ProfilePageResolver } from './profile.resolver';
10 |
11 | import { AngularFireAuthGuard, redirectUnauthorizedTo } from '@angular/fire/auth-guard';
12 |
13 | const redirectUnauthorizedToLogin = () => redirectUnauthorizedTo(['sign-in']);
14 |
15 | const routes: Routes = [
16 | {
17 | path: '',
18 | component: ProfilePage,
19 | canActivate: [AngularFireAuthGuard],
20 | data: { authGuardPipe: redirectUnauthorizedToLogin },
21 | resolve: {
22 | data: ProfilePageResolver
23 | }
24 | }
25 | ];
26 |
27 | @NgModule({
28 | imports: [
29 | CommonModule,
30 | FormsModule,
31 | IonicModule,
32 | RouterModule.forChild(routes),
33 | ],
34 | declarations: [ProfilePage],
35 | providers: [ProfilePageResolver]
36 | })
37 | export class ProfilePageModule {}
38 |
--------------------------------------------------------------------------------
/src/app/profile/profile.page.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 | {{user.name}}
16 | {{user.description}}
17 |
18 |
19 |
20 |
21 | Mobile
22 |
23 | {{user.phoneNumber}}
24 |
25 |
26 |
27 | Email
28 |
29 | {{user.email}}
30 |
31 |
32 |
33 | Auth Provider
34 |
35 | {{user.provider}}
36 |
37 |
38 |
39 | Sign out
40 |
41 |
42 |
43 |
--------------------------------------------------------------------------------
/src/app/profile/profile.page.scss:
--------------------------------------------------------------------------------
1 | .profile-content {
2 | --padding-bottom: 16px;
3 | --padding-end: 16px;
4 | --padding-start: 16px;
5 | --padding-top: 16px;
6 |
7 | .user-image {
8 | border-radius: 4%;
9 | }
10 |
11 | .user-details-wrapper {
12 | justify-content: center;
13 |
14 | .user-image-wrapper {
15 | text-align: center;
16 | }
17 |
18 | .user-info-wrapper {
19 | text-align: center;
20 | }
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/src/app/profile/profile.page.spec.ts:
--------------------------------------------------------------------------------
1 | import { async, ComponentFixture, TestBed } from '@angular/core/testing';
2 | import { IonicModule } from '@ionic/angular';
3 |
4 | import { ProfilePage } from './profile.page';
5 |
6 | describe('ProfilePage', () => {
7 | let component: ProfilePage;
8 | let fixture: ComponentFixture;
9 |
10 | beforeEach(async(() => {
11 | TestBed.configureTestingModule({
12 | declarations: [ ProfilePage ],
13 | imports: [IonicModule.forRoot()]
14 | }).compileComponents();
15 |
16 | fixture = TestBed.createComponent(ProfilePage);
17 | component = fixture.componentInstance;
18 | fixture.detectChanges();
19 | }));
20 |
21 | it('should create', () => {
22 | expect(component).toBeTruthy();
23 | });
24 | });
25 |
--------------------------------------------------------------------------------
/src/app/profile/profile.page.ts:
--------------------------------------------------------------------------------
1 | import { Component, OnInit } from '@angular/core';
2 | import { ActivatedRoute, Router } from '@angular/router';
3 | import { ProfileModel } from './profile.model';
4 | import { FirebaseAuthService } from '../firebase-auth.service';
5 |
6 | @Component({
7 | selector: 'app-profile',
8 | templateUrl: './profile.page.html',
9 | styleUrls: ['./profile.page.scss'],
10 | })
11 | export class ProfilePage implements OnInit {
12 | user: ProfileModel;
13 |
14 | constructor(
15 | private router: Router,
16 | private route: ActivatedRoute,
17 | private authService: FirebaseAuthService
18 | ) { }
19 |
20 | ngOnInit() {
21 | this.route.data
22 | .subscribe((result) => {
23 | this.user = result['data'];
24 | }, (err) => {})
25 | }
26 |
27 | signOut() {
28 | this.authService.signOut().subscribe(() => {
29 | // Sign-out successful.
30 | this.router.navigate(['sign-in']);
31 | }, (error) => {
32 | console.log('signout error', error);
33 | });
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/src/app/profile/profile.resolver.ts:
--------------------------------------------------------------------------------
1 | import { Injectable } from '@angular/core';
2 | import { Resolve } from '@angular/router';
3 | import { FirebaseAuthService } from '../firebase-auth.service';
4 |
5 | @Injectable()
6 | export class ProfilePageResolver implements Resolve {
7 |
8 | constructor(private firebaseAuthService: FirebaseAuthService) {}
9 |
10 | resolve() {
11 | return this.firebaseAuthService.getProfileDataSource();
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/src/app/sign-in/sign-in.module.ts:
--------------------------------------------------------------------------------
1 | import { NgModule } from '@angular/core';
2 | import { CommonModule } from '@angular/common';
3 | import { IonicModule } from '@ionic/angular';
4 | import { FormsModule, ReactiveFormsModule } from '@angular/forms';
5 | import { SignInPage } from './sign-in.page';
6 | import { Routes, RouterModule } from '@angular/router';
7 |
8 | const routes: Routes = [
9 | {
10 | path: '',
11 | component: SignInPage,
12 | }
13 | ];
14 |
15 | @NgModule({
16 | imports: [
17 | CommonModule,
18 | FormsModule,
19 | ReactiveFormsModule,
20 | IonicModule,
21 | RouterModule.forChild(routes),
22 | ],
23 | declarations: [SignInPage]
24 | })
25 | export class SignInPageModule {}
26 |
--------------------------------------------------------------------------------
/src/app/sign-in/sign-in.page.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Sign In with Firebase
8 |
9 |
49 |
50 |
51 |
Or
52 |
Facebook Sign In
53 |
Google Sign In
54 |
55 |
56 |
57 |
--------------------------------------------------------------------------------
/src/app/sign-in/sign-in.page.scss:
--------------------------------------------------------------------------------
1 | .sign-in-content {
2 | text-align: center;
3 | --padding-bottom: 16px;
4 | --padding-end: 16px;
5 | --padding-start: 16px;
6 | --padding-top: 16px;
7 |
8 | .auth-title {
9 | font-weight: bold;
10 | margin-bottom: 64px;
11 | letter-spacing: 0.6px;
12 | }
13 |
14 | .social-auth-options {
15 | .options-divider {
16 | text-align: center;
17 | }
18 | }
19 |
20 | .inputs-list {
21 | .input-item {
22 | --padding-start: 0px;
23 | --padding-end: 0px;
24 | --inner-padding-end: 0px;
25 | }
26 | }
27 |
28 | .error-container {
29 | .error-message {
30 | margin: 16px 0px;
31 | display: flex;
32 | align-items: center;
33 | color: var(--ion-color-danger);
34 | font-size: 14px;
35 |
36 | ion-icon {
37 | font-size: 16px;
38 | padding-inline-end: 8px;
39 | }
40 | }
41 | }
42 |
43 | .sign-in-btn {
44 | margin: 16px 0px;
45 | }
46 |
47 | .sign-up-btn-wrapper {
48 | justify-content: flex-end;
49 | align-items: center;
50 |
51 | .sign-up-btn {
52 | --padding-end: 0px;
53 | }
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/src/app/sign-in/sign-in.page.spec.ts:
--------------------------------------------------------------------------------
1 | import { async, ComponentFixture, TestBed } from '@angular/core/testing';
2 | import { IonicModule } from '@ionic/angular';
3 |
4 | import { SignInPage } from './sign-in.page';
5 |
6 | describe('SignInPage', () => {
7 | let component: SignInPage;
8 | let fixture: ComponentFixture;
9 |
10 | beforeEach(async(() => {
11 | TestBed.configureTestingModule({
12 | declarations: [ SignInPage ],
13 | imports: [IonicModule.forRoot()]
14 | }).compileComponents();
15 |
16 | fixture = TestBed.createComponent(SignInPage);
17 | component = fixture.componentInstance;
18 | fixture.detectChanges();
19 | }));
20 |
21 | it('should create', () => {
22 | expect(component).toBeTruthy();
23 | });
24 | });
25 |
--------------------------------------------------------------------------------
/src/app/sign-in/sign-in.page.ts:
--------------------------------------------------------------------------------
1 | import { Component, NgZone } from '@angular/core';
2 | import { AngularFireAuth } from '@angular/fire/auth';
3 | import { FormGroup, FormControl, Validators } from '@angular/forms';
4 | import { Router } from '@angular/router';
5 | import { FirebaseAuthService } from '../firebase-auth.service';
6 | import { Subscription } from 'rxjs';
7 |
8 | @Component({
9 | selector: 'app-sign-in',
10 | templateUrl: 'sign-in.page.html',
11 | styleUrls: ['sign-in.page.scss'],
12 | })
13 | export class SignInPage {
14 | signInForm: FormGroup;
15 | submitError: string;
16 | authRedirectResult: Subscription;
17 |
18 | validation_messages = {
19 | 'email': [
20 | { type: 'required', message: 'Email is required.' },
21 | { type: 'pattern', message: 'Enter a valid email.' }
22 | ],
23 | 'password': [
24 | { type: 'required', message: 'Password is required.' },
25 | { type: 'minlength', message: 'Password must be at least 6 characters long.' }
26 | ]
27 | };
28 |
29 | constructor(
30 | public angularFire: AngularFireAuth,
31 | public router: Router,
32 | private ngZone: NgZone,
33 | private authService: FirebaseAuthService
34 | ) {
35 | this.signInForm = new FormGroup({
36 | 'email': new FormControl('', Validators.compose([
37 | Validators.required,
38 | Validators.pattern('^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+.[a-zA-Z0-9-.]+$')
39 | ])),
40 | 'password': new FormControl('', Validators.compose([
41 | Validators.minLength(6),
42 | Validators.required
43 | ]))
44 | });
45 |
46 | // Get firebase authentication redirect result invoken when using signInWithRedirect()
47 | // signInWithRedirect() is only used when client is in web but not desktop
48 | this.authRedirectResult = this.authService.getRedirectResult()
49 | .subscribe(result => {
50 | if (result.user) {
51 | this.redirectLoggedUserToProfilePage();
52 | } else if (result.error) {
53 | this.submitError = result.error;
54 | }
55 | });
56 | }
57 |
58 | // Once the auth provider finished the authentication flow, and the auth redirect completes,
59 | // redirect the user to the profile page
60 | redirectLoggedUserToProfilePage() {
61 | // As we are calling the Angular router navigation inside a subscribe method, the navigation will be triggered outside Angular zone.
62 | // That's why we need to wrap the router navigation call inside an ngZone wrapper
63 | this.ngZone.run(() => {
64 | this.router.navigate(['profile']);
65 | });
66 | }
67 |
68 | signInWithEmail() {
69 | this.authService.signInWithEmail(this.signInForm.value['email'], this.signInForm.value['password'])
70 | .then(user => {
71 | // navigate to user profile
72 | this.redirectLoggedUserToProfilePage();
73 | })
74 | .catch(error => {
75 | this.submitError = error.message;
76 | });
77 | }
78 |
79 | facebookSignIn() {
80 | this.authService.signInWithFacebook()
81 | .then((result: any) => {
82 | if (result.additionalUserInfo) {
83 | this.authService.setProviderAdditionalInfo(result.additionalUserInfo.profile);
84 | }
85 | // This gives you a Facebook Access Token. You can use it to access the Facebook API.
86 | // const token = result.credential.accessToken;
87 | // The signed-in user info is in result.user;
88 | this.redirectLoggedUserToProfilePage();
89 | }).catch((error) => {
90 | // Handle Errors here.
91 | console.log(error);
92 | });
93 | }
94 |
95 | googleSignIn() {
96 | this.authService.signInWithGoogle()
97 | .then((result: any) => {
98 | if (result.additionalUserInfo) {
99 | this.authService.setProviderAdditionalInfo(result.additionalUserInfo.profile);
100 | }
101 | // This gives you a Google Access Token. You can use it to access the Google API.
102 | // const token = result.credential.accessToken;
103 | // The signed-in user info is in result.user;
104 | this.redirectLoggedUserToProfilePage();
105 | }).catch((error) => {
106 | // Handle Errors here.
107 | console.log(error);
108 | });
109 | }
110 |
111 | twitterSignIn() {
112 | this.authService.signInWithTwitter()
113 | .then((result: any) => {
114 | if (result.additionalUserInfo) {
115 | this.authService.setProviderAdditionalInfo(result.additionalUserInfo.profile);
116 | }
117 | // This gives you a Twitter Access Token. You can use it to access the Twitter API.
118 | // const token = result.credential.accessToken;
119 | // The signed-in user info is in result.user;
120 | this.redirectLoggedUserToProfilePage();
121 | }).catch((error) => {
122 | // Handle Errors here.
123 | console.log(error);
124 | });
125 | }
126 | }
127 |
--------------------------------------------------------------------------------
/src/app/sign-up/sign-up.module.ts:
--------------------------------------------------------------------------------
1 | import { NgModule } from '@angular/core';
2 | import { CommonModule } from '@angular/common';
3 | import { FormsModule, ReactiveFormsModule } from '@angular/forms';
4 |
5 | import { IonicModule } from '@ionic/angular';
6 |
7 | import { SignUpPage } from './sign-up.page';
8 | import { Routes, RouterModule } from '@angular/router';
9 |
10 | const routes: Routes = [
11 | {
12 | path: '',
13 | component: SignUpPage,
14 | }
15 | ];
16 |
17 | @NgModule({
18 | imports: [
19 | CommonModule,
20 | FormsModule,
21 | ReactiveFormsModule,
22 | IonicModule,
23 | RouterModule.forChild(routes),
24 | ],
25 | declarations: [SignUpPage]
26 | })
27 | export class SignUpPageModule {}
28 |
--------------------------------------------------------------------------------
/src/app/sign-up/sign-up.page.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 | Sign Up with Firebase
12 |
13 |
53 |
54 |
55 |
Or
56 |
Facebook Sign Up
57 |
Google Sign Up
58 |
59 |
60 |
61 |
--------------------------------------------------------------------------------
/src/app/sign-up/sign-up.page.scss:
--------------------------------------------------------------------------------
1 | .sign-up-content {
2 | text-align: center;
3 | --padding-bottom: 16px;
4 | --padding-end: 16px;
5 | --padding-start: 16px;
6 | --padding-top: 16px;
7 |
8 | .auth-title {
9 | font-weight: bold;
10 | margin-bottom: 64px;
11 | letter-spacing: 0.6px;
12 | }
13 |
14 | .social-auth-options {
15 | .options-divider {
16 | text-align: center;
17 | }
18 | }
19 |
20 | .inputs-list {
21 | .input-item {
22 | --padding-start: 0px;
23 | --padding-end: 0px;
24 | --inner-padding-end: 0px;
25 | }
26 | }
27 |
28 | .error-container {
29 | .error-message {
30 | margin: 16px 0px;
31 | display: flex;
32 | align-items: center;
33 | color: var(--ion-color-danger);
34 | font-size: 14px;
35 |
36 | ion-icon {
37 | font-size: 16px;
38 | padding-inline-end: 8px;
39 | }
40 | }
41 | }
42 |
43 | .sign-up-btn {
44 | margin: 16px 0px;
45 | }
46 |
47 | .sign-in-btn-wrapper {
48 | justify-content: flex-end;
49 | align-items: center;
50 |
51 | .sign-in-btn {
52 | --padding-end: 0px;
53 | }
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/src/app/sign-up/sign-up.page.spec.ts:
--------------------------------------------------------------------------------
1 | import { async, ComponentFixture, TestBed } from '@angular/core/testing';
2 | import { IonicModule } from '@ionic/angular';
3 |
4 | import { SignUpPage } from './sign-up.page';
5 |
6 | describe('SignUpPage', () => {
7 | let component: SignUpPage;
8 | let fixture: ComponentFixture;
9 |
10 | beforeEach(async(() => {
11 | TestBed.configureTestingModule({
12 | declarations: [ SignUpPage ],
13 | imports: [IonicModule.forRoot()]
14 | }).compileComponents();
15 |
16 | fixture = TestBed.createComponent(SignUpPage);
17 | component = fixture.componentInstance;
18 | fixture.detectChanges();
19 | }));
20 |
21 | it('should create', () => {
22 | expect(component).toBeTruthy();
23 | });
24 | });
25 |
--------------------------------------------------------------------------------
/src/app/sign-up/sign-up.page.ts:
--------------------------------------------------------------------------------
1 | import { Component, NgZone } from '@angular/core';
2 | import { AngularFireAuth } from '@angular/fire/auth';
3 | import { Router } from '@angular/router';
4 | import { FormGroup, FormControl, Validators } from '@angular/forms';
5 | import { FirebaseAuthService } from '../firebase-auth.service';
6 | import { Subscription } from 'rxjs';
7 |
8 | @Component({
9 | selector: 'app-sign-up',
10 | templateUrl: './sign-up.page.html',
11 | styleUrls: ['./sign-up.page.scss'],
12 | })
13 | export class SignUpPage {
14 | signUpForm: FormGroup;
15 | submitError: string;
16 | authRedirectResult: Subscription;
17 |
18 | validation_messages = {
19 | 'email': [
20 | { type: 'required', message: 'Email is required.' },
21 | { type: 'pattern', message: 'Enter a valid email.' }
22 | ],
23 | 'password': [
24 | { type: 'required', message: 'Password is required.' },
25 | { type: 'minlength', message: 'Password must be at least 6 characters long.' }
26 | ]
27 | };
28 |
29 | constructor(
30 | public angularFire: AngularFireAuth,
31 | public router: Router,
32 | private ngZone: NgZone,
33 | private authService: FirebaseAuthService
34 | ) {
35 | this.signUpForm = new FormGroup({
36 | 'email': new FormControl('', Validators.compose([
37 | Validators.required,
38 | Validators.pattern('^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+.[a-zA-Z0-9-.]+$')
39 | ])),
40 | 'password': new FormControl('', Validators.compose([
41 | Validators.minLength(6),
42 | Validators.required
43 | ]))
44 | });
45 | // Get firebase authentication redirect result invoken when using signInWithRedirect()
46 | // signInWithRedirect() is only used when client is in web but not desktop
47 | this.authRedirectResult = this.authService.getRedirectResult()
48 | .subscribe(result => {
49 | if (result.user) {
50 | this.redirectLoggedUserToProfilePage();
51 | } else if (result.error) {
52 | this.submitError = result.error;
53 | }
54 | });
55 | }
56 |
57 | // Once the auth provider finished the authentication flow, and the auth redirect completes,
58 | // redirect the user to the profile page
59 | redirectLoggedUserToProfilePage() {
60 | // As we are calling the Angular router navigation inside a subscribe method, the navigation will be triggered outside Angular zone.
61 | // That's why we need to wrap the router navigation call inside an ngZone wrapper
62 | this.ngZone.run(() => {
63 | this.router.navigate(['profile']);
64 | });
65 | }
66 |
67 | signUpWithEmail() {
68 | this.authService.signUpWithEmail(this.signUpForm.value['email'], this.signUpForm.value['password'])
69 | .then(user => {
70 | // navigate to user profile
71 | this.redirectLoggedUserToProfilePage();
72 | })
73 | .catch(error => {
74 | this.submitError = error.message;
75 | });
76 | }
77 |
78 | facebookSignUp() {
79 | this.authService.signInWithFacebook()
80 | .then((result: any) => {
81 | if (result.additionalUserInfo) {
82 | this.authService.setProviderAdditionalInfo(result.additionalUserInfo.profile);
83 | }
84 | // This gives you a Facebook Access Token. You can use it to access the Facebook API.
85 | // const token = result.credential.accessToken;
86 | // The signed-in user info is in result.user;
87 | this.redirectLoggedUserToProfilePage();
88 | }).catch((error) => {
89 | // Handle Errors here.
90 | console.log(error);
91 | });
92 | }
93 |
94 | googleSignUp() {
95 | this.authService.signInWithGoogle()
96 | .then((result: any) => {
97 | if (result.additionalUserInfo) {
98 | this.authService.setProviderAdditionalInfo(result.additionalUserInfo.profile);
99 | }
100 | // This gives you a Google Access Token. You can use it to access the Google API.
101 | // const token = result.credential.accessToken;
102 | // The signed-in user info is in result.user;
103 | this.redirectLoggedUserToProfilePage();
104 | }).catch((error) => {
105 | // Handle Errors here.
106 | console.log(error);
107 | });
108 | }
109 |
110 | twitterSignUp() {
111 | this.authService.signInWithTwitter()
112 | .then((result: any) => {
113 | if (result.additionalUserInfo) {
114 | this.authService.setProviderAdditionalInfo(result.additionalUserInfo.profile);
115 | }
116 | // This gives you a Twitter Access Token. You can use it to access the Twitter API.
117 | // const token = result.credential.accessToken;
118 | // The signed-in user info is in result.user;
119 | this.redirectLoggedUserToProfilePage();
120 | }).catch((error) => {
121 | // Handle Errors here.
122 | console.log(error);
123 | });
124 | }
125 | }
126 |
--------------------------------------------------------------------------------
/src/assets/icon/favicon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ionicthemes/ionic5-firebase-authentication/c599afaddf333e94b7c7bfc4c906b216c47bb252/src/assets/icon/favicon.png
--------------------------------------------------------------------------------
/src/assets/shapes.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/src/environments/environment.prod.ts:
--------------------------------------------------------------------------------
1 | export const environment = {
2 | production: true,
3 | firebase: {
4 | apiKey: "AIzaSyB_hifCjvJb7jf3hnZozfzlnJQ6N0iYuXI",
5 | authDomain: "ionic5-firebase-authentication.firebaseapp.com",
6 | databaseURL: "https://ionic5-firebase-authentication.firebaseio.com",
7 | projectId: "ionic5-firebase-authentication",
8 | }
9 | };
10 |
--------------------------------------------------------------------------------
/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 | firebase: {
8 | apiKey: "AIzaSyB_hifCjvJb7jf3hnZozfzlnJQ6N0iYuXI",
9 | authDomain: "ionic5-firebase-authentication.firebaseapp.com",
10 | databaseURL: "https://ionic5-firebase-authentication.firebaseio.com",
11 | projectId: "ionic5-firebase-authentication",
12 | }
13 | };
14 |
15 | /*
16 | * For easier debugging in development mode, you can import the following file
17 | * to ignore zone related error stack frames such as `zone.run`, `zoneDelegate.invokeTask`.
18 | *
19 | * This import should be commented out in production mode because it will have a negative impact
20 | * on performance if an error is thrown.
21 | */
22 | // import 'zone.js/dist/zone-error'; // Included with Angular CLI.
23 |
--------------------------------------------------------------------------------
/src/global.scss:
--------------------------------------------------------------------------------
1 | /*
2 | * App Global CSS
3 | * ----------------------------------------------------------------------------
4 | * Put style rules here that you want to apply globally. These styles are for
5 | * the entire app and not just one component. Additionally, this file can be
6 | * used as an entry point to import other CSS/Sass files to be included in the
7 | * output CSS.
8 | * For more information on global stylesheets, visit the documentation:
9 | * https://ionicframework.com/docs/layout/global-stylesheets
10 | */
11 |
12 | /* Core CSS required for Ionic components to work properly */
13 | @import "~@ionic/angular/css/core.css";
14 |
15 | /* Basic CSS for apps built with Ionic */
16 | @import "~@ionic/angular/css/normalize.css";
17 | @import "~@ionic/angular/css/structure.css";
18 | @import "~@ionic/angular/css/typography.css";
19 | @import '~@ionic/angular/css/display.css';
20 |
21 | /* Optional CSS utils that can be commented out */
22 | @import "~@ionic/angular/css/padding.css";
23 | @import "~@ionic/angular/css/float-elements.css";
24 | @import "~@ionic/angular/css/text-alignment.css";
25 | @import "~@ionic/angular/css/text-transformation.css";
26 | @import "~@ionic/angular/css/flex-utils.css";
27 |
--------------------------------------------------------------------------------
/src/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Ionic App
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/src/main.ts:
--------------------------------------------------------------------------------
1 | import { enableProdMode } from '@angular/core';
2 | import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
3 |
4 | import { AppModule } from './app/app.module';
5 | import { environment } from './environments/environment';
6 |
7 | if (environment.production) {
8 | enableProdMode();
9 | }
10 |
11 | platformBrowserDynamic().bootstrapModule(AppModule)
12 | .catch(err => console.log(err));
13 |
--------------------------------------------------------------------------------
/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/guide/browser-support
15 | */
16 |
17 | /***************************************************************************************************
18 | * BROWSER POLYFILLS
19 | */
20 |
21 | /** IE10 and IE11 requires the following for NgClass support on SVG elements */
22 | // import 'classlist.js'; // Run `npm install --save classlist.js`.
23 |
24 | /**
25 | * Web Animations `@angular/platform-browser/animations`
26 | * Only required if AnimationBuilder is used within the application and using IE/Edge or Safari.
27 | * Standard animation support in Angular DOES NOT require any polyfills (as of Angular 6.0).
28 | */
29 | // import 'web-animations-js'; // Run `npm install --save web-animations-js`.
30 |
31 | /**
32 | * By default, zone.js will patch all possible macroTask and DomEvents
33 | * user can disable parts of macroTask/DomEvents patch by setting following flags
34 | * because those flags need to be set before `zone.js` being loaded, and webpack
35 | * will put import in the top of bundle, so user need to create a separate file
36 | * in this directory (for example: zone-flags.ts), and put the following flags
37 | * into that file, and then add the following code before importing zone.js.
38 | * import './zone-flags.ts';
39 | *
40 | * The flags allowed in zone-flags.ts are listed here.
41 | *
42 | * The following flags will work for all browsers.
43 | *
44 | * (window as any).__Zone_disable_requestAnimationFrame = true; // disable patch requestAnimationFrame
45 | * (window as any).__Zone_disable_on_property = true; // disable patch onProperty such as onclick
46 | * (window as any).__zone_symbol__BLACK_LISTED_EVENTS = ['scroll', 'mousemove']; // disable patch specified eventNames
47 | *
48 | * in IE/Edge developer tools, the addEventListener will also be wrapped by zone.js
49 | * with the following flag, it will bypass `zone.js` patch for IE/Edge
50 | *
51 | * (window as any).__Zone_enable_cross_context_check = true;
52 | *
53 | */
54 |
55 | import './zone-flags';
56 |
57 | /***************************************************************************************************
58 | * Zone JS is required by default for Angular itself.
59 | */
60 |
61 | import 'zone.js/dist/zone'; // Included with Angular CLI.
62 |
63 |
64 | /***************************************************************************************************
65 | * APPLICATION IMPORTS
66 | */
67 |
--------------------------------------------------------------------------------
/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-testing';
4 | import { getTestBed } from '@angular/core/testing';
5 | import {
6 | BrowserDynamicTestingModule,
7 | platformBrowserDynamicTesting
8 | } 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 | // And load the modules.
20 | context.keys().map(context);
21 |
--------------------------------------------------------------------------------
/src/theme/variables.scss:
--------------------------------------------------------------------------------
1 | // Ionic Variables and Theming. For more info, please see:
2 | // http://ionicframework.com/docs/theming/
3 |
4 | /** Ionic CSS Variables **/
5 | :root {
6 | /** primary **/
7 | --ion-color-primary: #3880ff;
8 | --ion-color-primary-rgb: 56, 128, 255;
9 | --ion-color-primary-contrast: #ffffff;
10 | --ion-color-primary-contrast-rgb: 255, 255, 255;
11 | --ion-color-primary-shade: #3171e0;
12 | --ion-color-primary-tint: #4c8dff;
13 |
14 | /** secondary **/
15 | --ion-color-secondary: #3dc2ff;
16 | --ion-color-secondary-rgb: 61, 194, 255;
17 | --ion-color-secondary-contrast: #ffffff;
18 | --ion-color-secondary-contrast-rgb: 255, 255, 255;
19 | --ion-color-secondary-shade: #36abe0;
20 | --ion-color-secondary-tint: #50c8ff;
21 |
22 | /** tertiary **/
23 | --ion-color-tertiary: #5260ff;
24 | --ion-color-tertiary-rgb: 82, 96, 255;
25 | --ion-color-tertiary-contrast: #ffffff;
26 | --ion-color-tertiary-contrast-rgb: 255, 255, 255;
27 | --ion-color-tertiary-shade: #4854e0;
28 | --ion-color-tertiary-tint: #6370ff;
29 |
30 | /** success **/
31 | --ion-color-success: #2dd36f;
32 | --ion-color-success-rgb: 45, 211, 111;
33 | --ion-color-success-contrast: #ffffff;
34 | --ion-color-success-contrast-rgb: 255, 255, 255;
35 | --ion-color-success-shade: #28ba62;
36 | --ion-color-success-tint: #42d77d;
37 |
38 | /** warning **/
39 | --ion-color-warning: #ffc409;
40 | --ion-color-warning-rgb: 255, 196, 9;
41 | --ion-color-warning-contrast: #000000;
42 | --ion-color-warning-contrast-rgb: 0, 0, 0;
43 | --ion-color-warning-shade: #e0ac08;
44 | --ion-color-warning-tint: #ffca22;
45 |
46 | /** danger **/
47 | --ion-color-danger: #eb445a;
48 | --ion-color-danger-rgb: 235, 68, 90;
49 | --ion-color-danger-contrast: #ffffff;
50 | --ion-color-danger-contrast-rgb: 255, 255, 255;
51 | --ion-color-danger-shade: #cf3c4f;
52 | --ion-color-danger-tint: #ed576b;
53 |
54 | /** dark **/
55 | --ion-color-dark: #222428;
56 | --ion-color-dark-rgb: 34, 36, 40;
57 | --ion-color-dark-contrast: #ffffff;
58 | --ion-color-dark-contrast-rgb: 255, 255, 255;
59 | --ion-color-dark-shade: #1e2023;
60 | --ion-color-dark-tint: #383a3e;
61 |
62 | /** medium **/
63 | --ion-color-medium: #92949c;
64 | --ion-color-medium-rgb: 146, 148, 156;
65 | --ion-color-medium-contrast: #ffffff;
66 | --ion-color-medium-contrast-rgb: 255, 255, 255;
67 | --ion-color-medium-shade: #808289;
68 | --ion-color-medium-tint: #9d9fa6;
69 |
70 | /** light **/
71 | --ion-color-light: #f4f5f8;
72 | --ion-color-light-rgb: 244, 245, 248;
73 | --ion-color-light-contrast: #000000;
74 | --ion-color-light-contrast-rgb: 0, 0, 0;
75 | --ion-color-light-shade: #d7d8da;
76 | --ion-color-light-tint: #f5f6f9;
77 | }
78 |
79 | @media (prefers-color-scheme: dark) {
80 | /*
81 | * Dark Colors
82 | * -------------------------------------------
83 | */
84 |
85 | body {
86 | --ion-color-primary: #428cff;
87 | --ion-color-primary-rgb: 66,140,255;
88 | --ion-color-primary-contrast: #ffffff;
89 | --ion-color-primary-contrast-rgb: 255,255,255;
90 | --ion-color-primary-shade: #3a7be0;
91 | --ion-color-primary-tint: #5598ff;
92 |
93 | --ion-color-secondary: #50c8ff;
94 | --ion-color-secondary-rgb: 80,200,255;
95 | --ion-color-secondary-contrast: #ffffff;
96 | --ion-color-secondary-contrast-rgb: 255,255,255;
97 | --ion-color-secondary-shade: #46b0e0;
98 | --ion-color-secondary-tint: #62ceff;
99 |
100 | --ion-color-tertiary: #6a64ff;
101 | --ion-color-tertiary-rgb: 106,100,255;
102 | --ion-color-tertiary-contrast: #ffffff;
103 | --ion-color-tertiary-contrast-rgb: 255,255,255;
104 | --ion-color-tertiary-shade: #5d58e0;
105 | --ion-color-tertiary-tint: #7974ff;
106 |
107 | --ion-color-success: #2fdf75;
108 | --ion-color-success-rgb: 47,223,117;
109 | --ion-color-success-contrast: #000000;
110 | --ion-color-success-contrast-rgb: 0,0,0;
111 | --ion-color-success-shade: #29c467;
112 | --ion-color-success-tint: #44e283;
113 |
114 | --ion-color-warning: #ffd534;
115 | --ion-color-warning-rgb: 255,213,52;
116 | --ion-color-warning-contrast: #000000;
117 | --ion-color-warning-contrast-rgb: 0,0,0;
118 | --ion-color-warning-shade: #e0bb2e;
119 | --ion-color-warning-tint: #ffd948;
120 |
121 | --ion-color-danger: #ff4961;
122 | --ion-color-danger-rgb: 255,73,97;
123 | --ion-color-danger-contrast: #ffffff;
124 | --ion-color-danger-contrast-rgb: 255,255,255;
125 | --ion-color-danger-shade: #e04055;
126 | --ion-color-danger-tint: #ff5b71;
127 |
128 | --ion-color-dark: #f4f5f8;
129 | --ion-color-dark-rgb: 244,245,248;
130 | --ion-color-dark-contrast: #000000;
131 | --ion-color-dark-contrast-rgb: 0,0,0;
132 | --ion-color-dark-shade: #d7d8da;
133 | --ion-color-dark-tint: #f5f6f9;
134 |
135 | --ion-color-medium: #989aa2;
136 | --ion-color-medium-rgb: 152,154,162;
137 | --ion-color-medium-contrast: #000000;
138 | --ion-color-medium-contrast-rgb: 0,0,0;
139 | --ion-color-medium-shade: #86888f;
140 | --ion-color-medium-tint: #a2a4ab;
141 |
142 | --ion-color-light: #222428;
143 | --ion-color-light-rgb: 34,36,40;
144 | --ion-color-light-contrast: #ffffff;
145 | --ion-color-light-contrast-rgb: 255,255,255;
146 | --ion-color-light-shade: #1e2023;
147 | --ion-color-light-tint: #383a3e;
148 | }
149 |
150 | /*
151 | * iOS Dark Theme
152 | * -------------------------------------------
153 | */
154 |
155 | .ios body {
156 | --ion-background-color: #000000;
157 | --ion-background-color-rgb: 0,0,0;
158 |
159 | --ion-text-color: #ffffff;
160 | --ion-text-color-rgb: 255,255,255;
161 |
162 | --ion-color-step-50: #0d0d0d;
163 | --ion-color-step-100: #1a1a1a;
164 | --ion-color-step-150: #262626;
165 | --ion-color-step-200: #333333;
166 | --ion-color-step-250: #404040;
167 | --ion-color-step-300: #4d4d4d;
168 | --ion-color-step-350: #595959;
169 | --ion-color-step-400: #666666;
170 | --ion-color-step-450: #737373;
171 | --ion-color-step-500: #808080;
172 | --ion-color-step-550: #8c8c8c;
173 | --ion-color-step-600: #999999;
174 | --ion-color-step-650: #a6a6a6;
175 | --ion-color-step-700: #b3b3b3;
176 | --ion-color-step-750: #bfbfbf;
177 | --ion-color-step-800: #cccccc;
178 | --ion-color-step-850: #d9d9d9;
179 | --ion-color-step-900: #e6e6e6;
180 | --ion-color-step-950: #f2f2f2;
181 |
182 | --ion-toolbar-background: #0d0d0d;
183 |
184 | --ion-item-background: #000000;
185 | }
186 |
187 |
188 | /*
189 | * Material Design Dark Theme
190 | * -------------------------------------------
191 | */
192 |
193 | .md body {
194 | --ion-background-color: #121212;
195 | --ion-background-color-rgb: 18,18,18;
196 |
197 | --ion-text-color: #ffffff;
198 | --ion-text-color-rgb: 255,255,255;
199 |
200 | --ion-border-color: #222222;
201 |
202 | --ion-color-step-50: #1e1e1e;
203 | --ion-color-step-100: #2a2a2a;
204 | --ion-color-step-150: #363636;
205 | --ion-color-step-200: #414141;
206 | --ion-color-step-250: #4d4d4d;
207 | --ion-color-step-300: #595959;
208 | --ion-color-step-350: #656565;
209 | --ion-color-step-400: #717171;
210 | --ion-color-step-450: #7d7d7d;
211 | --ion-color-step-500: #898989;
212 | --ion-color-step-550: #949494;
213 | --ion-color-step-600: #a0a0a0;
214 | --ion-color-step-650: #acacac;
215 | --ion-color-step-700: #b8b8b8;
216 | --ion-color-step-750: #c4c4c4;
217 | --ion-color-step-800: #d0d0d0;
218 | --ion-color-step-850: #dbdbdb;
219 | --ion-color-step-900: #e7e7e7;
220 | --ion-color-step-950: #f3f3f3;
221 |
222 | --ion-item-background: #1e1e1e;
223 |
224 | --ion-toolbar-background: #1f1f1f;
225 |
226 | --ion-tab-bar-background: #1f1f1f;
227 | }
228 | }
--------------------------------------------------------------------------------
/src/zone-flags.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * Prevents Angular change detection from
3 | * running with certain Web Component callbacks
4 | */
5 | (window as any).__Zone_disable_customElements = true;
6 |
--------------------------------------------------------------------------------
/tsconfig.app.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "./tsconfig.json",
3 | "compilerOptions": {
4 | "outDir": "./out-tsc/app",
5 | "types": []
6 | },
7 | "include": [
8 | "src/**/*.ts"
9 | ],
10 | "exclude": [
11 | "src/test.ts",
12 | "src/**/*.spec.ts"
13 | ]
14 | }
15 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compileOnSave": false,
3 | "compilerOptions": {
4 | "baseUrl": "./",
5 | "outDir": "./dist/out-tsc",
6 | "sourceMap": true,
7 | "declaration": false,
8 | "module": "esnext",
9 | "moduleResolution": "node",
10 | "emitDecoratorMetadata": true,
11 | "experimentalDecorators": true,
12 | "importHelpers": true,
13 | "target": "es2015",
14 | "typeRoots": [
15 | "node_modules/@types"
16 | ],
17 | "lib": [
18 | "es2018",
19 | "dom"
20 | ]
21 | },
22 | "angularCompilerOptions": {
23 | "fullTemplateTypeCheck": true,
24 | "strictInjectionParameters": true
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/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 | "src/zone-flags.ts",
13 | "src/polyfills.ts"
14 | ],
15 | "include": [
16 | "src/**/*.spec.ts",
17 | "src/**/*.d.ts"
18 | ]
19 | }
20 |
--------------------------------------------------------------------------------
/tslint.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "tslint:recommended",
3 | "rulesDirectory": [
4 | "codelyzer"
5 | ],
6 | "rules": {
7 | "align": {
8 | "options": [
9 | "parameters",
10 | "statements"
11 | ]
12 | },
13 | "array-type": false,
14 | "arrow-parens": false,
15 | "arrow-return-shorthand": true,
16 | "curly": true,
17 | "deprecation": {
18 | "severity": "warn"
19 | },
20 | "eofline": true,
21 | "import-blacklist": [
22 | true,
23 | "rxjs/Rx"
24 | ],
25 | "import-spacing": true,
26 | "indent": {
27 | "options": [
28 | "spaces"
29 | ]
30 | },
31 | "interface-name": false,
32 | "max-classes-per-file": false,
33 | "max-line-length": [
34 | true,
35 | 140
36 | ],
37 | "member-access": false,
38 | "member-ordering": [
39 | true,
40 | {
41 | "order": [
42 | "static-field",
43 | "instance-field",
44 | "static-method",
45 | "instance-method"
46 | ]
47 | }
48 | ],
49 | "no-consecutive-blank-lines": false,
50 | "no-console": [
51 | true,
52 | "debug",
53 | "info",
54 | "time",
55 | "timeEnd",
56 | "trace"
57 | ],
58 | "no-empty": false,
59 | "no-inferrable-types": [
60 | true,
61 | "ignore-params"
62 | ],
63 | "no-non-null-assertion": true,
64 | "no-redundant-jsdoc": true,
65 | "no-switch-case-fall-through": true,
66 | "no-var-requires": false,
67 | "object-literal-key-quotes": [
68 | true,
69 | "as-needed"
70 | ],
71 | "object-literal-sort-keys": false,
72 | "ordered-imports": false,
73 | "quotemark": [
74 | true,
75 | "single"
76 | ],
77 | "semicolon": {
78 | "options": [
79 | "always"
80 | ]
81 | },
82 | "space-before-function-paren": {
83 | "options": {
84 | "anonymous": "never",
85 | "asyncArrow": "always",
86 | "constructor": "never",
87 | "method": "never",
88 | "named": "never"
89 | }
90 | },
91 | "trailing-comma": false,
92 | "no-output-on-prefix": true,
93 | "no-inputs-metadata-property": true,
94 | "no-host-metadata-property": true,
95 | "no-input-rename": true,
96 | "no-output-rename": true,
97 | "typedef-whitespace": {
98 | "options": [
99 | {
100 | "call-signature": "nospace",
101 | "index-signature": "nospace",
102 | "parameter": "nospace",
103 | "property-declaration": "nospace",
104 | "variable-declaration": "nospace"
105 | },
106 | {
107 | "call-signature": "onespace",
108 | "index-signature": "onespace",
109 | "parameter": "onespace",
110 | "property-declaration": "onespace",
111 | "variable-declaration": "onespace"
112 | }
113 | ]
114 | },
115 | "use-lifecycle-interface": true,
116 | "use-pipe-transform-interface": true,
117 | "one-variable-per-declaration": false,
118 | "component-class-suffix": [true, "Page", "Component"],
119 | "directive-class-suffix": true,
120 | "directive-selector": [
121 | true,
122 | "attribute",
123 | "app",
124 | "camelCase"
125 | ],
126 | "component-selector": [
127 | true,
128 | "element",
129 | "app",
130 | "page",
131 | "kebab-case"
132 | ]
133 | , "variable-name": {
134 | "options": [
135 | "ban-keywords",
136 | "check-format",
137 | "allow-pascal-case"
138 | ]
139 | },
140 | "whitespace": {
141 | "options": [
142 | "check-branch",
143 | "check-decl",
144 | "check-operator",
145 | "check-separator",
146 | "check-type",
147 | "check-typecast"
148 | ]
149 | }
150 | }
151 | }
152 |
--------------------------------------------------------------------------------