Giter VIP home page Giter VIP logo

angularfire's Introduction

AngularFire

AngularFire smooths over the rough edges an Angular developer might encounter when implementing the framework-agnostic Firebase JS SDK & aims to provide a more natural developer experience by conforming to Angular conventions.

ng add @angular/fire

  • Dependency injection - Provide and Inject Firebase services in your components
  • Zone.js wrappers - Stable zones allow proper functionality of service workers, forms, SSR, and pre-rendering
  • Observable based - Utilize RxJS rather than callbacks for realtime streams
  • NgRx friendly API - Integrate with NgRx using AngularFire's action based APIs.
  • Lazy-loading - AngularFire dynamically imports much of Firebase, reducing time to load your app
  • Deploy schematics - Get your Angular application deployed on Firebase Hosting with a single command
  • Google Analytics - Zero-effort Angular Router awareness in Google Analytics
  • Router Guards - Guard your Angular routes with built-in Firebase Authentication checks

Example use

import { provideFirebaseApp, getApp, initializeApp } from '@angular/fire/app';
import { getFirestore, provideFirestore } from '@angular/fire/firestore';

@NgModule({
  imports: [
    provideFirebaseApp(() => initializeApp({ ... })),
    provideFirestore(() => getFirestore()),
  ],
  ...
})
export class AppModule { }
import { inject } from '@angular/core';
import { Firestore, collectionData, collection } from '@angular/fire/firestore';
import { Observable } from 'rxjs';

interface Item {
  name: string,
  ...
};

@Component({
  selector: 'app-root',
  template: `
  <ul>
    <li *ngFor="let item of item$ | async">
      {{ item.name }}
    </li>
  </ul>
  `
})
export class AppComponent {
  item$: Observable<Item[]>;
  firestore: Firestore = inject(Firestore);

  constructor() {
    const itemCollection = collection(this.firestore, 'items');
    this.item$ = collectionData(itemCollection);
  }
}

Polyfills

Neither AngularFire or Firebase ship with polyfills. To have compatibility across as wide-range of environments we suggest the following polyfills be added to your application:

API Environments Suggested Polyfill License
Various ES5+ features Safari < 10 core-js/stable MIT
globalThis Chrome < 71
Safari < 12.1
iOS < 12.2
Node < 12
globalThis MIT
Proxy Safari < 10 proxy-polyfill Apache 2.0
fetch Safari < 10.1
iOS < 10.3
cross-fetch MIT

Resources

Quickstart - Get your first application up and running by following our quickstart guide.

Contributing

Stackblitz Template - Remember to set your Firebase configuration in app/app.module.ts.

Upgrading to v7.0? Check out our guide.

Sample apps

We have three sample apps in this repository:

  1. samples/compat a kitchen sink application that demonstrates use of the "compatibility" API
  2. samples/modular a kitchen sink application that demonstrates the new tree-shakable API
  3. samples/advanced the same app as samples/modular but demonstrates more advanced concepts such as Angular Universal state-transfer, dynamically importing Firebase feature modules, and Firestore data bundling.

Having troubles?

Get help on our Q&A board, the official Firebase Mailing List, the Firebase Community Slack (#angularfire2), the Angular Community Discord (#firebase), Gitter, the Firebase subreddit, or Stack Overflow.

NOTE: AngularFire is maintained by Googlers but is not a supported Firebase product. Questions on the mailing list and issues filed here are answered on a best-effort basis by maintainers and other community members. If you are able to reproduce a problem with Firebase outside of AngularFire's implementation, please file an issue on the Firebase JS SDK or reach out to the personalized Firebase support channel.

Developer Guide

This developer guide assimes you're using the new tree-shakable AngularFire API, if you're looking for the compatability API you can find the documentation here.

See the v7 upgrade guide for more information on this change..

Firebase product integrations

import { } from '@angular/fire/analytics';
import { } from '@angular/fire/auth';
import { } from '@angular/fire/firestore';
import { } from '@angular/fire/functions';
import { } from '@angular/fire/messaging';
import { } from '@angular/fire/storage';
import { } from '@angular/fire/performance';
import { } from '@angular/fire/database';
import { } from '@angular/fire/remote-config';
import { } from '@angular/fire/app-check';

Deploying your site

  • Deploy to Firebase Hosting
  • Angular Universal: Deploy to Cloud Functions
  • Angular Universal: Deploy to Cloud Run

angularfire's People

Contributors

bananer avatar bob-lee avatar cartant avatar codediodeio avatar danielsogl avatar davideast avatar dependabot[bot] avatar fabien0102 avatar goldblatt avatar hiepxanh avatar jamesdaniels avatar jeffbcross avatar jteplitz avatar jymdman avatar kingdarboja avatar maistho avatar markgoho avatar mikedory avatar mukesh51 avatar myspivey avatar nothingeverhappens avatar orahul1 avatar piusnyakoojo avatar redian avatar robertisaac avatar robwormald avatar ryanclark avatar sarunint avatar splaktar avatar valentinfunk avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

angularfire's Issues

bug(FirebaseList): doesn't update when the whole path is removed

Presumably could listen to the value event of the child, and check if the snapshot is null.

For example, if the list is myfirebase/questions, and the questions path itself is removed, the synchronized array is not updated, and client still sees old list of questions.

bug(e2e): Firebase test-server causes websocket errors

Right now the e2e test is communicating with a real Firebase.

When this file is run, and then an app is opened to connect to it, many ERR_CONNECTION_CLOSED errors are logged to the console.

Virtual host configuration:

127.0.0.1       test.firebaseio.com

Ping test.firebaseio.com:

PING test.firebaseio.com (127.0.0.1): 56 data bytes

To Reproduce

  1. Check out this branch;
  2. Run ./node_modules/.bin/http-server from the root of the project
  3. Open http://localhost:8080/test/e2e/firebase_list/
  4. Look at console

Unwrapping DataSnapshots

Currently the providers automatically unwrap the DataSnapshots returned from the Firebase database.

Should we provide an option to keep the DataSnapshot intact?

class MyComponent {
  constructor(private af: AngularFire) {
    const obj = af.object('/name', { snapshot: true });
    obj.subscribe((snap) => {
      console.log(snap); 
    });
  }
}

Or perhaps we could use generics

class MyComponent {
  constructor(private af: AngularFire) {
    const obj = af.object<DataSnapshot>('/name');
    obj.subscribe((snap) => {
      console.log(snap); 
    });
  }
}

Write Contributor Docs

  • Describe how to set up virtual hosts for firebase-server
  • E2E testing and unit testing instructions

@FirebaseList and @FirebaseObject design

Goal: Have a declarative means of getting a Firebase reference into a component, to be used in a view.

Proposal:

@Component({
  selector: 'posts-list',
  changeDetection: ChangeDetectionStrategy. OnPush
  template: `
  <ul>
    <li *ngFor="#post in posts | async">
      {{post.val().title}} 
      <button (click)="posts.remove(post)">X</button>
    </li>
  </ul>
  `
})
class PostsList {
  @FirebaseList({
    path: 'https://<FIREBASE>/posts' // Should eventually support relative to an injectable root.
  }) posts:Observable<Post>;

The @FirebaseList decorator would create a subclassed Observable and set it to posts. The Observable would contain methods for updating the data. It's generally considered bad practice to add non-combinator methods to an Observable, but there was no cleaner alternative that came to mind (I'm hoping for ideas!). Since the type is an Observable it can be unwrapped with the async pipe inside the template, and can take advantage of OnPush change detection to only perform dirty checking when a new array has been emitted from the Observable.

The FirebaseListObservable would support save, add, and remove similar to AngularFire, as well as lookup helpers to find items by key or find index of an item.

This design has the values inside the list as wrapped Firebase objects instead of POJS, which means .val() must be called inside the template. This is to make it easier to update data without having to reverse lookup records. There could be a pipe that would unwrap all objects, or developers could just map themselves:

<li *ngFor="#post in posts | af_unwrap | async">
class PostsList {
  postsUnwrapped:Observable<Post>;
  @FirebaseList(...) posts:Observable<Firebase>;
  constructor() {
    this.postsUnwrapped = this.posts.map(v => v.val());
  }
}

This decorator is called @FirebaseList. There will be a separate decorator with similar semantics but for objects, called @FirebaseObject.

Querying

Query operators may optionally be supplied to the decorator:

@FirebaseList({
  path: 'https://<FIREBASE>/posts',
  query: [['orderByChild', 'timestamp'], ['limitToFirst', 2]]
})

Prior Art https://www.firebase.com/docs/web/libraries/angular/api.html#angularfire-firebasearray

The utilities used to make this functionality would carry over to the yet-to-be-designed Firebase pipe. The pipe would probably be the preferred tool for developers not familiar with, or able to use decorators.

I've got a branch with a functioning FirebaseList decorator that I'll push soon.

feat(AngularFire): single injectable service for all APIs

In order to simplify getting a hold of AngularFire APIs via DI, a single service could contain all AngularFire APIs (authentication, getting a list, getting a root reference, etc).

With the current API surface, the service could look like:

interface AngularFire {
  auth: AuthObservable; // Pending merge of #33
  list: FirebaseListFactory;
  object: FirebaseObjectFactory; // Not yet implemented
  ref: RefFactory; // Not yet implemented
}
@Component(...)
class QuestionsList { 
  this.orderProp: string = 'askedTime';
  this.pageSize: Observable<number>;
  constructor(private af:AngularFire) {
    this.questions = af.list('/questions', {
      query: {
         orderBy: this.orderProp
         limitToFirst: this.pageSize
      }]
    })
  }
}
@Component({
  template: `
    <h1 *ngIf="af.auth | async">Welcome, {{(af.auth | async).github.userName}}</h1>
  `
})
class Login {
  constructor(private af:AngularFire) {
  }
}

feat(firebaseRef): consider exposing firebase events as an Observable

Scenario - i'd like to use AngularFire/Firebase in a redux/rxjs style app, where i might mix and match data from various sources. Rather than using a FirebaseObservable directly, I might want to get an Observable of the raw events emitting by a firebaseRef. ('child_added' etc)

FIREBASE_PROVIDERS, defaultFirebase issue

The inclusion of defaultFirebase in my provider,

providers: [HeroService, defaultFirebase('https://myUrl.firebaseio.com')];

or FIREBASE_PROVIDERS and defaultFirebase in my bootStrap,

bootstrap(AppComponent, [FIREBASE_PROVIDERS, defaultFirebase('https://myUrl.firebaseio.com')]);

causes my app to hang indefinitely. if I remove these definitions, the app again loads correctly. No error messages are issued.

Is this a known issue?

My github repo is here: https://github.com/TheoMer/angular2firebase2

angularfire2.ts referencing incorrect path

angularfire2.ts is exporting:export * from './angularfire2/angularfire2';, but when I cloned the project, the real path locally was './src/angularfire2' and I had to change the folder name or the path to get the references to be recognized.

Is this the intended behavior? It might be nice to rename the folder or change the path?

General query about angularfire2 approach

I'm not sure this is the right place to raise this query, so if there's a better place for the discussion, please point me there :)

With an angular2 app, my approach so far has been to separate out different concerns into services. So if I have a component that needs some data, I'd go and create a service with methods like:

public getNavigation(): Observable<MenuItem[]>

Methods that returns an observable of that data that my component can subscribe.
Then I can inject that re-usable service into one or more components. I can also mock that service so that my component is testable in isolation without it changing any real data.
And my components don't have a concrete dependency on Firebase, it just wants observable's of data which could come from a variety of systems and services.

So I'm not sure about the approach in this library at the moment. Do I want my components to be referencing firebase directly, or query logic and suchlike within the component? How do a write tests for this?

I think I'd rather angularfire2 just gave me mapped/synchronized objects and arrays wrapped in an observable rather than things I put directly in a component.

I'd be interested in people's thoughts.

typings install postinstall is broken

npm ERR! Darwin 15.3.0
npm ERR! argv "/node/v5.5.0/bin/node" "/node/v5.5.0/bin/npm" "install" "--save" "angularfire2"
npm ERR! node v5.5.0
npm ERR! npm  v3.6.0
npm ERR! file sh
npm ERR! code ELIFECYCLE
npm ERR! errno ENOENT
npm ERR! syscall spawn

npm ERR! [email protected] postinstall: `typings install`
npm ERR! spawn ENOENT
npm ERR!
npm ERR! Failed at the [email protected] postinstall script 'typings install'.
npm ERR! Make sure you have the latest version of node.js and npm installed.
npm ERR! If you do, this is most likely a problem with the angularfire2 package,
npm ERR! not with npm itself.
npm ERR! Tell the author that this fails on your system:
npm ERR!     typings install
npm ERR! You can get information on how to open an issue for this project with:
npm ERR!     npm bugs angularfire2
npm ERR! Or if that isn't available, you can get their info via:
npm ERR!     npm owner ls angularfire2
npm ERR! There is likely additional logging output above.

npm ERR! Please include the following file with any support request:
npm ERR!     /Projects/angularfire-demo-2851/npm-debug.log

Explore using "FirebaseOperators" for perf and ergonomics.

Discussed this briefly with @jeffbcross last week, adding it here for posterity and discussion:

Scenario -

Imagine I have a FirebaseList Observable that is pushing arrays of values out:

this.foos = angularFire.list('/foos');

and I want to select / query / etc some value(s) out of that list.

Locally, I can do it using basic Rx operators:

this.foos.filter(foos => foos.filter(foo => foo.val().bar_id === 1))

This works fine, but it means that the entire collection is getting delivered, which could be improved.

Since an Observable is lazy, in theory we could use a set of "Firebase Operators" to augment a "query object", which once subscribed to offloads as much logic as possible to the firebase backend.

Example using the firebase .equalTo API:

angularFire.list('/foos').orderByChild('bar_id').equalTo(1).subscribe(...)

TODO: figure out how to actually make this work - it's quite different than a normal Rx operator in that it has to pass query params etc "backwards", so I don't know if its something we would need to implement a bunch of custom logic for or what. In theory those fbOperators would just be implemented on the original FirebaseObservable and mutate some query object.

cc @Blesh if he's got any bright ideas here.

example of firebase query API https://www.firebase.com/docs/web/api/query/equalto.html

feat(Auth): Web-Worker friendly Authentication

Since first-class third-party oauth methods (Facebook, Github, Twitter, Google) require a popup window or redirect, they don't play very nicely with Web Workers where neither popups or redirects are possible without some communication with the UI thread...because there's no window object, and the location object is more-or-less read only and doesn't represent the same thing as in the UI thread.

So, after some deliberation with @jteplitz602 looking at the options, the option that seems most doable in the meantime is to have a way to keep the Firebase SDK in the UI thread, and proxy messages back and forth with the Web Worker.

So for users using Web Worker, they will:

  • Use WORKER_RENDER_PROVIDERS in the main thread.
  • Use WORKER_APP_PROVIDERS in the worker.
  • The Firebase SDK will NOT be able to be directly used in the worker, so the application will be limited to whatever features AngularFire supports. (They could technically use it, but it will be a terrible experience with out-of-sync data between contexts).

This will have some performance impact from marshaling data from UI -> Worker -> UI, but this is not expected to be significant.

The longer term plan would be to work with Firebase team to add better support for this use case in the SDK.

feat(Auth): Add Account Management Features

For password auth firebase exposes a number of methods for account management (creation, changing email, setting security rules, etc...). We should expose a way to access those (or decide if we just want to let people use the SDK instead)

Initial setup not working

I am trying to run angularfire2 but it is not running getting an error:

Error: SyntaxError: Unexpected token <(…)Zone.run @ angular2-polyfills.js:1243zoneBoundFn @ angular2-polyfills.js:1220lib$es6$promise$$internal$$tryCatch @ angular2-polyfills.js:468lib$es6$promise$$internal$$invokeCallback @ angular2-polyfills.js:480lib$es6$promise$$internal$$publish @ angular2-polyfills.js:451lib$es6$promise$$internal$$publishRejection @ angular2-polyfills.js:401(anonymous function) @ angular2-polyfills.js:123Zone.run @ angular2-polyfills.js:1243zoneBoundFn @ angular2-polyfills.js:1220lib$es6$promise$asap$$flush @ angular2-polyfills.js:262
angular2-polyfills.js:1152
screenshot 2016-03-12 17 41 52

The complete project source has been uploaded here:
https://github.com/panacloud/learn-angular2/tree/master/step_extra_angularfire2_basic

ship system.register bundle

I pulled down angularfire2 from npm, added the script reference to my html and got cracking trying things out, and very quickly hit an issue that the typescript has been compiled in a way that needs require to work.

As an angular2 novice, I started with the guide from the docs (https://angular.io/docs/ts/latest/quickstart.html) and so have used the tsconfig.json they've outlined there. The angular2 js files themselves from npm are also using system.js.

Should this library not have the same typescript compilation settings to angular2?
Or perhaps I'm thinking about this wrong, maybe the npm package should include the ts files instead of the js, so the user compiles it according to their own tsconfig?

fix(FirebaseListFactory): ref.off cannot be unbounded

Inside of the Subscriber function in FirebaseListFactory, the Firebase reference's off method is being returned to act as the disposal function:

let ref = new Firebase('...');
let obs = new FirebaseObservable(() => {
  return ref.off;
});

But when the Observable is unsubscribed, ref.off is being called with the wrong context.

Make build pipeline faster

Currently the build is just using tsc -w, which is analyzing a lot of sources on each pass, including all of Angular. Should use broccoli, based on what angular-cli generates.

Methods for FirebaseListObservable

Right now FirebaseObservable only supports add, the interface should support other methods:

interface IFirebaseObservable<T> {
  add(val: T): void;
  remove(key: string): void;
  getRecord(key: string): void;
  ref(): FirebaseRef;
}

FirebaseListObservable emits duplicate values for first insert

If I subscribe to an empty list, and then add a new value to that list it looks like that value is getting emitted twice. For example if I do:

let observable = this._angularFire.list('my_path', {preserveSnapshot: true});
observable.subscribe ((l) => {
  console.log('length', l.length);
});
setTimeout(() => {
  observable.add({text: 'new'});
}, 1);

If 'my_path' is initially empty this will output:
length 1
length 2

The 2 is erroneous and contains a duplicate entry.

It doesn't look like this problem occurs if 'my_path' is not initially empty.

Add CLI module

  • Interactively create a Firebase
    • Add providers for new or existing Firebase to an application
    • Incorporate angular-cli-firebase-hosting to deploy apps to Firebase
    • Add FirebaseList to an existing component
    • Publish to npm

fix(FirebaseObservable): add method incorrectly inherits generic type

When getting a FirebaseObservable via FirebaseListFactory, the add method expects to receive values of the same type as the generic value assigned to the Observable, which is any[]. Instead, the type should just be any or whatever subset of possible values is supported by FirebaseRef.push

chore(FirebaseList): separate FirebaseListFactory into separate module

The FirebaseListFactory function does the hard work of subscribing to a firebase path and providing a synchronized array to the user. Right now it lives inside providers/firebase_list. Since FirebaseListFactory will be used in different contexts (JS service and pipes, for example), it should be separated into its own file, such as utils/firebase_list_factory.ts

fix(package): make library npm link friendly

So that @robwormald will be happy.

The current npm package is published from within the dist directory. The package.json "main" field points to "angularfire.js" as the main file. When npm linking the repo, angularfire.js doesn't exist, and Rob has to rewrite the "main" field of package.json to "dist/angularfire.js", which makes Rob sad.

Instead, the package.json main field should point to dist/angularfire.js, and it should re-written when package.json is copied to dist/ in the publish process.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.