Skip to content

Commit

Permalink
Merged master.
Browse files Browse the repository at this point in the history
  • Loading branch information
jamesdaniels committed May 23, 2019
2 parents 2bff468 + e32164d commit 1d277f8
Show file tree
Hide file tree
Showing 58 changed files with 5,071 additions and 946 deletions.
11 changes: 6 additions & 5 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,9 @@ install:
script:
- yarn run build
- ./node_modules/.bin/karma start --single-run --browsers ChromeHeadlessTravis --reporters mocha
# Run integration test to make sure our typings are correct for user-land.
- node tools/run-typings-test.js
# Run the ng6 build test
- cd test/ng-build/ng6 && yarn && yarn build:prod
- |
./node_modules/.bin/karma start --single-run --browsers ChromeHeadlessTravis --reporters mocha &&
yarn test:node &&
node tools/run-typings-test.js &&
cd test/ng-build/ng6 &&
yarn && yarn build:prod
6 changes: 5 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -88,25 +88,29 @@ Firebase offers two cloud-based, client-accessible database solutions that suppo
### Authenticate users

- [Getting started with Firebase Authentication](docs/auth/getting-started.md)
- [Route users with AngularFire guards](docs/auth/router-guards.md)

### Upload files

- [Getting started with Cloud Storage](docs/storage/storage.md)

### Send push notifications

- [Getting started with Firebase Messaging](docs/messaging/messaging.md)

### Monitor your application performance in production

- [Getting started with Performance Monitoring](docs/performance/getting-started.md)

### Directly call Cloud Functions

- [Getting started with Callable Functions](docs/functions/functions.md)

### Deploying your application

> Firebase Hosting is production-grade web content hosting for developers. With Hosting, you can quickly and easily deploy web apps and static content to a global content delivery network (CDN) with a single command.
- [Deploy your Angular application on Firebase Hosting](docs/deploying-angularfire-to-firebase.md)
- [Deploy your application on Firebase Hosting](docs/deploy/getting-started.md)

#### Server-side rendering

Expand Down
27 changes: 27 additions & 0 deletions cloudbuild.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# See go/angularfire-releasing for details on the AngularFire release process.
# If you need to trigger a release manually, be sure to use substitutions like so:
# @canary `gcloud builds submit --substitutions=SHORT_SHA="9b0a0b0"`
# @next `gcloud builds submit --substitutions=TAG_NAME="v1.2.3-rc.1"`
# @latest `gcloud builds submit --substitutions=TAG_NAME="v1.2.3"`
steps:
- name: 'gcr.io/cloud-builders/yarn'
entrypoint: 'bash'
args: ["./tools/build.sh"]
env:
- 'TAG_NAME=$TAG_NAME'
- 'SHORT_SHA=$SHORT_SHA'

- name: 'gcr.io/cloud-builders/yarn'
entrypoint: 'bash'
args: ["./tools/test.sh"]

- name: 'gcr.io/cloud-builders/npm'
entrypoint: 'bash'
env: ['TAG_NAME=$TAG_NAME']
args: ["./tools/release.sh"]
secretEnv: ['NPM_TOKEN']

secrets:
- kmsKeyName: projects/angularfire/locations/global/keyRings/cloud-build/cryptoKeys/cloud-build
secretEnv:
NPM_TOKEN: CiQAwtE8WoPa1sNqAQJZ1WMODuJooVmO6zihz2hAZOfUmDsgogUSTQCq8yp8qgltY+8jWpAR9GuS1JaVhd+fTVRilqLtdi2yXSdiDPTzLhZ+30bMlAOcoc0PxhCBn3JOpn8H1xshX+mG8yK7xog2Uq+CLVx/
102 changes: 102 additions & 0 deletions docs/auth/router-guards.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
# Route users with AngularFire guards

`AngularFireAuthGuard` provides a prebuilt [`canActivate` Router Guard](https://angular.io/api/router/CanActivate) using `AngularFireAuth`. By default unauthenticated users are not permitted to navigate to protected routes:

```ts
import { AngularFireAuthGuard } from '@angular/fire/auth-guard';

export const routes: Routes = [
{ path: '', component: AppComponent },
{ path: 'items', component: ItemListComponent, canActivate: [AngularFireAuthGuard] },
]
```

## Customizing the behavior of `AngularFireAuthGuard`

To customize the behavior of `AngularFireAuthGuard`, you can pass an RXJS pipe through the route data's `authGuardPipe` key.

The `auth-guard` module provides the following pre-built pipes:

| Exported pipe | Functionality |
|-|-|
| `loggedIn` | The default pipe, rejects if the user is not authenticated. |
| `isNotAnonymous` | Rejects if the user is anonymous |
| `emailVerified` | Rejects if the user's email is not verified |
| `hasCustomClaim(claim)` | Rejects if the user does not have the specified claim |
| `redirectUnauthorizedTo(redirect)` | Redirect unauthenticated users to a different route |
| `redirectLoggedInTo(redirect)` | Redirect authenticated users to a different route |

Example use:

```ts
import { AngularFireAuthGuard, hasCustomClaim, redirectUnauthorizedTo, redirectLoggedInTo } from '@angular/fire/auth-guard';

const adminOnly = hasCustomClaim('admin');
const redirectUnauthorizedToLogin = redirectUnauthorizedTo(['login']);
const redirectLoggedInToItems = redirectLoggedInTo(['items']);
const belongsToAccount = (next) => hasCustomClaim(`account-${next.params.id}`);

export const routes: Routes = [
{ path: '', component: AppComponent },
{ path: 'login', component: LoginComponent, canActivate: [AngularFireAuthGuard], data: { authGuardPipe: redirectLoggedInToItems }},
{ path: 'items', component: ItemListComponent, canActivate: [AngularFireAuthGuard], data: { authGuardPipe: redirectUnauthorizedToLogin },
{ path: 'admin', component: AdminComponent, canActivate: [AngularFireAuthGuard], data: { authGuardPipe: adminOnly }},
{ path: 'accounts/:id', component: AdminComponent, canActivate: [AngularFireAuthGuard], data: { authGuardPipe: belongsToAccount }}
];
```
Use the provided `canActivate` helper and spread syntax to make your routes more readable:
```ts
import { canActivate } from '@angular/fire/auth-guard';

export const routes: Routes = [
{ path: '', component: AppComponent },
{ path: 'login', component: LoginComponent, ...canActivate(redirectLoggedInToItems) },
{ path: 'items', component: ItemListComponent, ...canActivate(redirectUnauthorizedToLogin) },
{ path: 'admin', component: AdminComponent, ...canActivate(adminOnly) },
{ path: 'accounts/:id', component: AdminComponent, ...canActivate(belongsToAccount) }
];
```
### Compose your own pipes
`AngularFireAuthGuard` pipes are RXJS operators which transform an optional User to a boolean or Array (for redirects). You can build easily build your own to customize behavior further:
```ts
import { map } from 'rxjs/operators';

// This pipe redirects a user to their "profile edit" page or the "login page" if they're unauthenticated
// { path: 'profile', ...canActivate(redirectToProfileEditOrLogin) }
const redirectToProfileEditOrLogin = map(user => user ? ['profiles', user.uid, 'edit'] : ['login']);
```
The `auth-guard` modules provides a `customClaims` operator to reduce boiler plate when checking a user's claims:
```ts
import { pipe } from 'rxjs';
import { map } from 'rxjs/operators';
import { customClaims } from '@angular/fire/auth-guard';

// This pipe will only allow users with the editor role to access the route
// { path: 'articles/:id/edit', component: ArticleEditComponent, ...canActivate(editorOnly) }
const editorOnly = pipe(customClaims, map(claims => claims.role === "editor"));
```
### Using router state
`AngularFireAuthGuard` will also accept `AuthPipeGenerator`s which generate `AuthPipe`s given the router state:
```ts
import { pipe } from 'rxjs';
import { map } from 'rxjs/operators';
import { customClaims } from '@angular/fire/auth-guard';

// Only allow navigation to the route if :userId matches the authenticated user's uid
// { path: 'user/:userId/edit', component: ProfileEditComponent, ...canActivate(onlyAllowSelf) }
const onlyAllowSelf = (next) => map(user => !!user && next.params.userId === user.uid);

// Only allow navigation to the route if the user has a custom claim matching :accountId
// { path: 'accounts/:accountId/billing', component: BillingDetailsComponent, ...canActivate(accountAdmin) }
const accountAdmin = (next) => pipe(customClaims, map(claims => claims[`account-${next.params.accountId}-role`] === "admin"));
```
66 changes: 66 additions & 0 deletions docs/deploy/getting-started.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
# Deploy your application on Firebase Hosting

In this guide, we'll look at how to use `@angular/fire` to automatically deploy an Angular application to Firebase hosting by using the Angular CLI.

## Step 1: add `@angular/fire` to your project

First, you need to add the `@angular/fire` package to your project. In your Angular CLI project run:

```shell
ng add @angular/fire
```

*Note that the command above assumes you have global Angular CLI installed. To install Angular CLI globally run `npm i -g @angular/cli`.*

The command above will trigger the `@angular/fire` `ng-add` schematics. The schematics will open a web browser and guide you through the Firebase authentication flow (if you're not signed in already). After you authenticate, you'll see a prompt to select a Firebase hosting project.

The schematics will do the following:

- Add `@angular/fire` to your list of dependencies
- Create `firebase.json`, `.firebaserc` files in the root of your workspace. You can use them to configure your firebase hosting deployment. Find more about them [here](https://firebase.google.com/docs/hosting/full-config)
- Update your workspace file (`angular.json`) by inserting the `deploy` builder

In the end, your `angular.json` project will look like below:

```json
{
"$schema": "./node_modules/@angular/cli/lib/config/schema.json",
"version": 1,
"newProjectRoot": "projects",
"projects": {
"sample-app": {
// ...
"deploy": {
"builder": "@angular/fire:deploy",
"options": {}
}
}
}
// ...
},
"defaultProject": "sample-app"
}
```

If you want to add deployment capabilities to a different project in your workspace, you can run:

```
ng add @angular/fire --project=[PROJECT_NAME]
```

## Step 2: deploying the project

As the second step, to deploy your project run:

```
ng run [ANGULAR_PROJECT_NAME]:deploy
```

The command above will trigger:

1. Production build of your application
2. Deployment of the produced assets to the firebase hosting project you selected during `ng add`

## Step 3: customization

To customize the deployment flow, you can use the configuration files you're already familiar with from `firebase-tools`. You can find more in the [firebase documentation](https://firebase.google.com/docs/hosting/full-config).
31 changes: 0 additions & 31 deletions docs/deploying-angularfire-to-firebase.md

This file was deleted.

19 changes: 19 additions & 0 deletions docs/firestore/querying-collections.md
Original file line number Diff line number Diff line change
Expand Up @@ -180,4 +180,23 @@ export class AppComponent {
}
```

## Collection Group Queries

To query across collections and sub-collections with the same name anywhere in Firestore, you can use collection group queries.

Collection Group Queries allow you to have a more nested data-structure without sacrificing performance. For example, we could easily query all comments a user posted; even if the comments were stored as a sub-collection under `Articles/**` or even nested deeply (`Articles/**/Comments/**/Comments/**/...`):

```ts
constructor(private afs: AngularFirestore) { }

ngOnInit() {
...
// Get all the user's comments, no matter how deeply nested
this.comments$ = afs.collectionGroup('Comments', ref => ref.where('user', '==', userId))
.valueChanges({ idField });
}
```

`collectionGroup` returns an `AngularFirestoreCollectionGroup` which is similar to `AngularFirestoreCollection`. The main difference is that `AngularFirestoreCollectionGroup` has no data operation methods such as `add` because it doesn't have a concrete reference.

### [Next Step: Getting started with Firebase Authentication](../auth/getting-started.md)
71 changes: 48 additions & 23 deletions docs/functions/functions.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,29 +26,6 @@ import { environment } from '../environments/environment';
export class AppModule {}
```

### Configure the Function region with the FunctionsRegionToken Injection Token

Allow configuration of Function region with the `FunctionsRegionToken` Injection Token by adding it to the `providers` section of your `NgModule`. The default is `us-central1`.

```ts
import { NgModule } from '@angular/core';
import { AngularFireFunctionsModule, FunctionsRegionToken } from '@angular/fire/functions';

@NgModule({
imports: [
...
AngularFireFunctionsModule,
...
],
...
providers: [
{ provide: FunctionsRegionToken, useValue: 'asia-northeast1' }
]
})
export class AppModule {}

```

### Injecting the AngularFireFunctions service

Once the `AngularFireFunctionsModule` is registered you can inject the `AngularFireFunctions` service.
Expand Down Expand Up @@ -91,3 +68,51 @@ export class AppComponent {
```

Notice that calling `httpsCallable()` does not initiate the request. It creates a function, which when called creates an Observable, subscribe or convert it to a Promise to initiate the request.

## Configuration via Dependency Injection

### Functions Region

Allow configuration of the Function's region by adding `FUNCTIONS_REGION` to the `providers` section of your `NgModule`. The default is `us-central1`.

```ts
import { NgModule } from '@angular/core';
import { AngularFireFunctionsModule, FUNCTIONS_REGION } from '@angular/fire/functions';

@NgModule({
imports: [
...
AngularFireFunctionsModule,
...
],
...
providers: [
{ provide: FUNCTIONS_REGION, useValue: 'asia-northeast1' }
]
})
export class AppModule {}

```

### Cloud Functions emulator

Point callable Functions to the Cloud Function emulator by adding `FUNCTIONS_ORIGIN` to the `providers` section of your `NgModule`.

```ts
import { NgModule } from '@angular/core';
import { AngularFireFunctionsModule, FUNCTIONS_ORIGIN } from '@angular/fire/functions';

@NgModule({
imports: [
...
AngularFireFunctionsModule,
...
],
...
providers: [
{ provide: FUNCTIONS_ORIGIN, useValue: 'http://localhost:5005' }
]
})
export class AppModule {}

```
2 changes: 1 addition & 1 deletion docs/universal/cloud-functions.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ After [setting up your application with Angular Universal as outlined in Getting
If you don't already have the Firebase CLI installed, do so:

```bash
npm i -g @firebase-tools
npm i -g firebase-tools
firebase login
```

Expand Down
Loading

0 comments on commit 1d277f8

Please sign in to comment.