Skip to content
This repository has been archived by the owner on Dec 14, 2022. It is now read-only.

Commit

Permalink
feat: added support for realtime updates using snapshot listeners
Browse files Browse the repository at this point in the history
It is now possible to listen to realtime update for documents and collection queries. Usage is
available in the README.

BREAKING CHANGE: Replaced @Google-Cloud dependency with firestore client SDK. Implementation of
realtime updates highlights discreptancies between the SDKS.
  • Loading branch information
lmcq committed Sep 2, 2019
1 parent dba4fb3 commit 663cadc
Show file tree
Hide file tree
Showing 81 changed files with 6,072 additions and 835 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@ coverage
.nyc_output
service-account.json
firebase-firestorm.code-workspace
.env
118 changes: 75 additions & 43 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ Firestorm is an [ORM](https://en.wikipedia.org/wiki/Object-relational_mapping)
for [firestore](https://firebase.google.com/docs/firestore) which can be used
with Typescript.

**This library currently only supports the [client Firebase SDK](https://github.com/firebase/firebase-js-sdk).**

## Contents

- [Requirements](#requirements)
Expand Down Expand Up @@ -134,7 +136,6 @@ import Comment from './Comment';
name: 'posts',
})
export default class Post extends Entity {
...
@subCollection({
name: 'comments',
entity: Comment, // we must define the entity class due to limitations in Typescript's reflection capabilities. Progress should be made on this issue in future releases.
Expand Down Expand Up @@ -171,7 +172,6 @@ import Author from './Author';
name: 'posts',
})
export default class Post extends Entity {
...
@documentRef({
name: 'author',
entity: Author, // we must define the entity class due to limitations in Typescript's reflection capabilities. Progress should be made on this issue in future releases.
Expand All @@ -190,11 +190,9 @@ use to manipulate the data.
##### Getting a document

```typescript
...
const post = Collection(Post).get('post-1').then((post : Post) => {
console.log(post);
});
...
```

##### Getting a subcollection
Expand All @@ -215,56 +213,96 @@ const commentCollection = postRef.collection(Post);

##### Querying data

You can use the `find(query : ICollectionQuery)` method to query data.
A full list of options are available in the
[docs](https://lmcq.github.io/firebase-firestorm/), but they are essentially
the same as what is available with firestore.
Calling `query()` on a collection will allow you to build queries in a [similar fashion to the standard Firestore SDK](https://firebase.google.com/docs/firestore/query-data/queries). You can build a query by chaining together methods, and finally calling the `get()` method to fetch the result. Omitting filters after the `query()` method will return all results from a collection.

```typescript
const posts = Collection(Post).find({
where: [
['title', '==', 'Example Title'],
...
],
});
// Build the query.
const query = Collection(Post)
.query()
.where('title', '==', 'Example Title');

// Fetch and manipulate the result.
query.get().then((snapshot): DocumentSnapshot<Post> => {
const post = snapshot.doc;
...
});
```

##### Creating documents

```typescript
...
const post = new Post();
post.id = 'post-1'; // id is optional, if it is not defined it will be generated by firestore.
post.title = 'Untitled';
let savedPost : Post;
Collection(Post).create(post).then((_savedPost : Post) => {
savedPost = _savedPost;
});
...
const post = new Post();
post.id = 'post-1'; // id is optional, if it is not defined it will be generated by firestore.
post.title = 'Untitled';
let savedPost : Post;
Collection(Post).create(post).then((_savedPost : Post) => {
savedPost = _savedPost;
});
```

##### Updating documents

```typescript
...
const post = new Post();
post.id = 'post-1'; // id is required.
post.title = 'Untitled';
let savedPost : Post;
Collection(Post).update(post).then((_savedPost : Post) => {
savedPost = _savedPost;
});
...
const post = new Post();
post.id = 'post-1'; // id is required.
post.title = 'Untitled';
let savedPost : Post;
Collection(Post).update(post).then((_savedPost: Post) => {
savedPost = _savedPost;
});
```

##### Removing documents

```typescript
...
Collection(Post).remove('post-id').then(...);
...
Collection(Post).remove('post-id').then(...);
```

#### 5. Realtime Updates

You can set up listeners for changes on either a single document, or a group of documents for a query. This is done a [similar way to the standard Firebase SDK](https://firebase.google.com/docs/firestore/query-data/listen).

##### Listening to document updates

You can attach a listener to a single document reference by using the `onSnapshot(callback)` method.

````typescript
Collection(Post).doc('post-id').onSnapshot(
(snapshot): DocumentSnapshot<Post> => {
const post: Post = snapshot.doc;
}
);
...
````

The callback function will executed once with the initial snapshot payload, and then for any subsequent updates to that document.

##### Listening to a collection (or query)

You can attach a listener to a group of documents in a collection by using the `onSnapshot(callback)` method on a collection query.

````typescript
Collection(Post).query().onSnapshot(
(snapshot): QuerySnapshot<Post> => {
const posts: Post[] = snapshot.docs;
}
);

// or

Collection(Post)
.query()
.where('title', '==', 'Example Title')
.onSnapshot(
(snapshot): QuerySnapshot<Post> => {
const posts: Post[] = snapshot.docs;
}
);
````
The callback function will executed once with the initial snapshot payload, and then for any subsequent updates to that query. As per the Firebase SDK, you call see the [document changes in each snapshot](https://firebase.google.com/docs/firestore/query-data/listen#view_changes_between_snapshots) using the `snapshot.docChanges()` method.



#### 6. Formatting data

An instance of entity maybe contain properties such as
Expand Down Expand Up @@ -347,12 +385,10 @@ class Nested {
And then to use this entity:

```typescript
...
const nested = new Nested();
nested.nestedProperty = 'test';
const example = new Example();
example.nestedObject = nested;
...
```

#### Geopoints
Expand All @@ -372,10 +408,8 @@ class Example extends Entity {
And then to assign a GeoPoint:

```typescript
...
const example = new Example();
example.geopoint = new Geopoint(latitude, longitude);
...
const example = new Example();
example.geopoint = new Geopoint(latitude, longitude);
```

#### Timestamps
Expand Down Expand Up @@ -417,9 +451,7 @@ reference's have the `I` infront of the type, e.g. `IDocumentRef`,

## Limitations

- Listening to document updates using snapshots is currently unsupported.
- Transactions and batched writes are currently unsupported.
- Offline persitences is unsupported.

If you would like to help resolve these issues, feel free
to make a a [pull request](#pull-requests).
Expand Down
2 changes: 1 addition & 1 deletion docs/assets/js/search.js

Large diffs are not rendered by default.

6 changes: 3 additions & 3 deletions docs/classes/caseconverter.html
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ <h3><span class="tsd-flag ts-flagStatic">Static</span> camel<wbr>ToKebab<wbr>Cas
<li class="tsd-description">
<aside class="tsd-sources">
<ul>
<li>Defined in utils/CaseConverter.ts:25</li>
<li>Defined in <a href="https://github.com/lmcq/firebase-firestorm/blob/dba4fb3/src/utils/CaseConverter.ts#L25">utils/CaseConverter.ts:25</a></li>
</ul>
</aside>
<div class="tsd-comment tsd-typography">
Expand Down Expand Up @@ -140,7 +140,7 @@ <h3><span class="tsd-flag ts-flagStatic">Static</span> camel<wbr>ToSnake<wbr>Cas
<li class="tsd-description">
<aside class="tsd-sources">
<ul>
<li>Defined in utils/CaseConverter.ts:11</li>
<li>Defined in <a href="https://github.com/lmcq/firebase-firestorm/blob/dba4fb3/src/utils/CaseConverter.ts#L11">utils/CaseConverter.ts:11</a></li>
</ul>
</aside>
<div class="tsd-comment tsd-typography">
Expand Down Expand Up @@ -174,7 +174,7 @@ <h3><span class="tsd-flag ts-flagStatic">Static</span> to<wbr>Camel<wbr>Case</h3
<li class="tsd-description">
<aside class="tsd-sources">
<ul>
<li>Defined in utils/CaseConverter.ts:39</li>
<li>Defined in <a href="https://github.com/lmcq/firebase-firestorm/blob/dba4fb3/src/utils/CaseConverter.ts#L39">utils/CaseConverter.ts:39</a></li>
</ul>
</aside>
<div class="tsd-comment tsd-typography">
Expand Down
Loading

0 comments on commit 663cadc

Please sign in to comment.