Skip to content

Commit 7aaa9f8

Browse files
committed
feat(afs): modified bug. document docs
1 parent 472cbad commit 7aaa9f8

File tree

6 files changed

+118
-7
lines changed

6 files changed

+118
-7
lines changed

docs/firestore/collections.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ There are multiple ways of streaming collection data from Firestore.
7474
### `valueChanges()`
7575
**What is it?** - Returns an Observable of data as a synchronized array of JSON objects. All Snapshot metadata is stripped and just the method provides only the data.
7676

77-
**Why would you use it?** - When you just need a list of data. No document metadata is attach to the resulting array which makes it simple to render to a view.
77+
**Why would you use it?** - When you just need a list of data. No document metadata is attached to the resulting array which makes it simple to render to a view.
7878

7979
**When would you not use it?** - When you need a more complex data structure than an array or you need the `id` of each document to use data manipulation metods. This method assumes you either are saving the `id` to the document data or using a "readonly" approach.
8080

docs/firestore/documents.md

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,110 @@
11
# Using Documents with Firestore
22

3+
## Understanding Documents
4+
5+
A Document is apart of a Collection. Firestore follows a `Collection > Document > Collection > Document` structure. Collections nested under a Document are not retrieved with a Document. You must explicitly retrieve the Collection underneath that path. This gives you a much more flexible structure. Gone are the days of worrying about pulling back the whole tree.
6+
7+
## Using an AngularFirestoreDocument
8+
9+
The `AngularFirestoreDocument` service is a wrapper around the native Firestore SDK's `DocumentReference` type. It is a generic service that provides you with a strongly typed set of methods for manipulating and streaming data. This service is designed for use as an `@Injectable()`.
10+
11+
```ts
12+
import { Component } from '@angular/core';
13+
import { AngularFirestore, AngularFirestoreDocument } from 'angularfire2/firestore';
14+
import { Observable } from 'rxjs/Observable';
15+
16+
@Component({
17+
selector: 'afs-app',
18+
template: `
19+
<div>
20+
{{ (item | async)?.name }}
21+
</div>
22+
`
23+
})
24+
export class AppComponent {
25+
private itemDoc: AngularFirestoreDocument<Item>:
26+
item: Observable<Item>;
27+
constructor(private afs: AngularFirestore): {
28+
this.itemDoc = afs.doc<Item>('items/1');
29+
this.item = this.itemDoc.valueChanges();
30+
}
31+
update(item: Item) {
32+
this.itemDoc.update(item);
33+
}
34+
}
35+
```
36+
37+
### The `DocumentChangeAction` type
38+
39+
With the exception of the `valueChanges()`, each streaming method returns an Observable of `DocumentChangeAction[]`.
40+
41+
A `DocumentChangeAction` gives you the `type` and `payload` properties. The `type` tells when what `DocumentChangeType` operation occured (`added`, `modified`, `removed`). The `payload` property is a `DocumentChange` which provides you important metdata about the change and a `doc` property which is the `DocumentSnapshot`.
42+
43+
```ts
44+
interface DocumentChangeAction {
45+
//'added' | 'modified' | 'removed';
46+
type: DocumentChangeType;
47+
payload: DocumentChange;
48+
}
49+
50+
interface DocumentChange {
51+
type: DocumentChangeType;
52+
doc: DocumentSnapshot;
53+
oldIndex: number;
54+
newIndex: number;
55+
}
56+
57+
interface DocumentSnapshot {
58+
exists: boolean;
59+
ref: DocumentReference;
60+
id: string;
61+
metadata: SnapshotMetadata;
62+
data(): DocumentData;
63+
get(fieldPath: string): any;
64+
}
65+
```
66+
67+
## Streaming document data
68+
69+
There are multiple ways of streaming collection data from Firestore.
70+
71+
### `valueChanges()`
72+
**What is it?** - Returns an Observable of document data. All Snapshot metadata is stripped and just the method provides only the data.
73+
74+
**Why would you use it?** - When you just need the object data. No document metadata is attached which makes it simple to render to a view.
75+
76+
**When would you not use it?** - When you need the `id` of the document to use data manipulation metods. This method assumes you either are saving the `id` to the document data or using a "readonly" approach.
77+
78+
### `snapshotChanges()`
79+
**What is it?** - Returns an Observable of data as a `DocumentChangeAction`.
80+
81+
**Why would you use it?** - When you need the document data but also want to keep around metadata. This metadata provides you the underyling `DocumentReference` and document id. Having the document's id around makes it easier to use data manipulation methods. This method gives you more horsepower with other Angular integrations such as ngrx, forms, and animations due to the `type` property. The `type` property on each `DocumentChangeAction` is useful for ngrx reducers, form states, and animation states.
82+
83+
**When would you not use it?** - When you simply need to render data to a view and don't want to do any extra processing.
84+
85+
## Manipulating documents
86+
87+
AngularFirestore provides methods for setting, updating, and deleting document data.
88+
89+
- `set(data: T)` - Destructively updates a document's data.
90+
- `update(data: T)` - Non-destructively updates a document's data.
91+
- `delete()` - Deletes an entire document. Does not delete any nested collections.
92+
93+
## Querying?
94+
95+
Querying has no effect on documents. Documents are a single object and querying effects a range of multiple documents. If you are looking for querying then you want to use a collection.
96+
97+
## Retrieving nested collections
98+
99+
Nesting collections is a great way to structure your data. This allows you to group related data structures together. If you are creating a "Task List" site, you can group "tasks" under a user: `user/<uid>/tasks`.
100+
101+
To retrieve a nested collection use the `collection(path: string)` method.
102+
103+
```ts
104+
constructor(private afs: AngularFirestore): {
105+
this.userDoc = afs.doc<Item>('user/david');
106+
this.tasks = this.userDoc.collection<Task>('tasks').valueChanges();
107+
}
108+
```
109+
110+
For more information about using collections read the collection documentation.

src/firestore/collection/changes.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ export function combineChange(combined: DocumentChange[], change: DocumentChange
6464
if(change.oldIndex !== change.newIndex) {
6565
combined.splice(change.oldIndex, 1);
6666
}
67-
combined.splice(change.newIndex, 0, change);
67+
combined.splice(change.newIndex, 1, change);
6868
break;
6969
case 'removed':
7070
combined.splice(change.oldIndex, 1);

src/firestore/collection/collection.spec.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ async function collectionHarness(afs: AngularFirestore, items: number, queryFn?:
2626
return { randomCollectionName, ref, stocks, names };
2727
}
2828

29-
describe('AngularFirestoreCollection', () => {
29+
fdescribe('AngularFirestoreCollection', () => {
3030
let app: firebase.app.App;
3131
let afs: AngularFirestore;
3232
let sub: Subscription;
@@ -78,11 +78,13 @@ describe('AngularFirestoreCollection', () => {
7878

7979
describe('snapshotChanges()', () => {
8080

81-
it('should listen to all snapshotChanges() by default', async (done) => {
81+
fit('should listen to all snapshotChanges() by default', async (done) => {
8282
const ITEMS = 10;
8383
let count = 0;
8484
const { randomCollectionName, ref, stocks, names } = await collectionHarness(afs, ITEMS);
8585
const sub = stocks.snapshotChanges().subscribe(data => {
86+
const ids = data.map(d => d.payload.doc.id);
87+
debugger;
8688
count = count + 1;
8789
// the first time should all be 'added'
8890
if(count === 1) {

src/firestore/document/document.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import { COMMON_CONFIG } from '../test-config';
1313

1414
import { Stock, randomName, FAKE_STOCK_DATA } from '../utils.spec';
1515

16-
describe('AngularFirestoreDocument', () => {
16+
fdescribe('AngularFirestoreDocument', () => {
1717
let app: firebase.app.App;
1818
let afs: AngularFirestore;
1919
let sub: Subscription;

src/firestore/observable/fromRef.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,11 @@ import { Action, Reference } from '../interfaces';
88
import 'rxjs/add/operator/map';
99

1010
function _fromRef<T, R>(ref: Reference<T>): Observable<R> {
11-
return new Observable(subscriber => {
11+
const ref$ = new Observable(subscriber => {
1212
const unsubscribe = ref.onSnapshot(subscriber);
1313
return { unsubscribe };
1414
});
15+
return observeOn.call(ref$, new ZoneScheduler(Zone.current));
1516
}
1617

1718
export function fromRef<R>(ref: DocumentReference | Query) {
@@ -20,7 +21,7 @@ export function fromRef<R>(ref: DocumentReference | Query) {
2021

2122
export function fromDocRef(ref: DocumentReference): Observable<Action<DocumentSnapshot>>{
2223
return fromRef<DocumentSnapshot>(ref)
23-
.map(payload => ({ payload, type: 'modified' }));
24+
.map(payload => ({ payload, type: 'value' }));
2425
}
2526

2627
export function fromCollectionRef(ref: Query): Observable<Action<QuerySnapshot>> {

0 commit comments

Comments
 (0)