npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@modelata/node-fire

v5.0.2

Published

Modelata abstract layer for firebase-admin sdk in node.js

Downloads

24

Readme

@modelata/node-fire

This library is a wrapper around firestore to implement kind of an ODM in Node.JS projects. It also can be used in Firestore cloud functions projects.

Compatibility

| firebase-admin | @modelata/fire | @modelata/node-fire | |----------------|----------------|---------------------| | 11.5.2 | ^5.0.0 | ^5.0.0 | | 10.0.2 | ^4.0.0 | ^4.0.0 |

Installation

npm i -s @modelata/node-fire firebase-admin reflect-metadata

Initialization

Init firebase-admin (cf their own documentation)

import * as admin from 'firebase-admin';

const serviceAccount = require('./serviceAccount.json');

admin.initializeApp({
  credential: admin.credential.cert(serviceAccount),
  databaseURL: `https://${serviceAccount.project_id}.firebaseio.com`,
  storageBucket: `${serviceAccount.project_id}.appspot.com`,
});

const settings = { timestampsInSnapshots: true };
const db = admin.firestore();
db.settings(settings);

const auth = admin.auth();

const storage = admin.storage().bucket();

Models

Basic

Your models must extend MFModel :

export class SomeModel extends MFModel<SomeModel> {
  name: string = null;

  constructor(
    data: Partial<SomeModel> = {},
    mustachePath?: string,
    location?: Partial<IMFLocation>,
  ) {
    super();
    super.initialize(data, mustachePath, location);
  }
}

COMMON ATTRIBUTES

modelata-node-fire set some attribute an all models.

  • _id : document id.
  • _collectionPath : document path.
  • _snapshot : document firestore snapshot.
  • updateDate : date of last update.
  • creationDate : creation date of document in db.
  • deleted : boolean used for soft deletion mode

Extended

You can use decorators on properties to extend your models :

@InsubDoc

  @InSubDoc('data/private')
  email: string = null;
  • @param subDocPath the path of the subdocument (WITHOUT main document path)

this property is from a subdocument

/!\ the DAO must extends MFFlattableDao

@AuthUserProperty

  @AuthUserProperty()
  email: string = null;

@StorageProperty

  @StorageProperty({
    deletePreviousOnUpdate: false,
    deleteOnDelete: true
  })
  picture: IMFFile = null;

this properties links to a file stored in storage The property must be of type : IMFFile.

DAOs

To manipulate your models in database, you need to create the corresponding DAOs :

Simple :

@CollectionPath('somes')
export class SomeDao extends MFDao<SomeModel> {
  constructor(database: FirebaseFirestore.Firestore) {
    super(database);
  }

  getNewModel(data?: Partial<SomeModel>, location?: Partial<IMFLocation>): SomeModel {
    return new SomeModel(data, this.mustachePath, location);
  }
}

Flattable if your model is made of data from subdocuments :

@CollectionPath('somes')
export class SomeDao extends MFFlattableDao<SomeModel> {
  constructor(db: FirebaseFirestore.Firestore) {
    super(db);
  }

  getNewModel(data?: Partial<SomeModel>, location?: Partial<IMFLocation>): SomeModel {
    const someModel = new SomeModel(data, this.mustachePath, location);
    return someModel;
  }
}

@CollectionPath decorator

@CollectionPath('/users')

CollectionPath decorator must be used on all DAO. CollectionPath take in parameter a string representing the collection path in firestore db. If the collection is a subcollection (collection in a document), use the "mustache" syntaxe for all document id.

@CollectionPath('/users/{userId}/mySubCollection/{mySubDocId}/subSubcollection')

All methods that need an id or a location (like "get"), now take a Location with ids mentioned in CollectionPath.

const location = {
  id: 'mySubSubDocId',
  mySubDocId: 'id',
  userId: 'id',
};

@DeletionMode decorator

@DeletionMode(MFDeleteMode.SOFT)

DeletionMode decorator is used for set the deletion strategy for this DAO. (default : HARD) DeletionMode take in parameter a enum value MFDeleteMode.SOFT or MFDeleteMode.HARD.

MFDeleteMode.SOFT :

  • when a dao delete a document (with delete methode), the document is just updated with delete = true;
  • all getList calls have a "where filter" on deleted field

MFDeleteMode.HARD :

  • when a dao delete a document (with delete methode), the document is definitely deleted.

PUBLIC METHOD

get

get(idOrLocation: string | IMFLocation, options?: IMFGetOneOptions)

Get a model from database from id or location

  • options :
export interface IMFGetOneOptions {
    /**
     * Document will include an hidden property containing document snapshote
     */
    withSnapshot?: boolean;
    /**
     * Observable returned will complete on first result
     */
    completeOnFirst?: boolean;
    /**
     * Request result will be cached in order to get a faster answer on same getOne request
     */
    cacheable?: boolean;
    /**
     * Display an error in console when requested document not exists (default: true)
     */
    warnOnMissing?: boolean;
}

getByReference

getByReference(reference: DocumentReference, options?: IMFGetOneOptions)

Get a model from database from its reference

getByPath

getByPath(path: string, options?: IMFGetOneOptions)

Get a model from database from its path

getList

getList(location?: MFOmit<IMFLocation, "id">, options?: IMFGetListOptions<M>)

Get a list of documents in the collection

  • options :
export interface IMFGetListOptions<M> {
  /**
   * Documents will include an hidden property containing document snapshote
   */
  withSnapshot?: boolean;

  /**
   * Observable returned will complete on first result
   */
  completeOnFirst?: boolean;

  /**
   * Where conditions
   */
  where?: IMFWhere[];

  /**
   * Order by
   */
  orderBy?: IMFOrderBy;

  /**
   * Maximum result returned
   */
  limit?: number;

  /**
   * boundary of the get, only one is applied
   */
  offset?: IMFOffset<M>;

  /**
   * Request result will be cached in order to get a faster answer on same getList request
   */
  cacheable?: boolean;
}

getReference

 getReference(idOrLocation: string | Partial<IMFLocation>)

Get the reference from an id (document only), a location (document or collection) or a model (document only)

update

update(data: Partial<M>, location?: string | IMFLocation | M, options?: IMFUpdateOptions<M>)

update some field of a model.

  • options :
/**
 * List of file properties of the model M for which stored files MUST (true) or MUST NOT be deleted on document update
 * (Overrides behaviour configured in model decorators)
 */
export type IMFDeletePreviousOnUpdateFilesOptions<M extends IMFModel<M>> = {
  /**
   * File property : true => the previous file will be deleted if updated
   * File property : false => the fprevious ile will NOT be deleted if updated
   */ [fileAttribute in NonFunctionPropertyNames<M>]?: boolean;
};

/**
 * Options to pass to update method
 */
export interface IMFUpdateOptions<M extends IMFModel<M>> {
  deletePreviousOnUpdateFiles?: IMFDeletePreviousOnUpdateFilesOptions<M>;
}

create

create(data: M, location?: string | Partial<IMFLocation>, options?: IMFSaveOptions)

save a new model in db, update if already exist.

  • options :
export interface IMFSaveOptions {
  /**
   * If document already exists, it will be fully overwritten
   */
  overwrite?: boolean;
}

delete

delete(idLocationOrModel: string | IMFLocation | M, options?: IMFDeleteOptions<M>)

Delete a model by id

/**
 * List of file properties of the model M for which stored files MUST (true) or MUST NOT be deleted on document deletion
 * (Overrides behaviour configured in model decorators)
 */
export declare type IMFDeleteOnDeleteFilesOptions<M extends IMFModel<M>> = {
  /**
   * File property : true => the file will be deleted
   * File property : false => the file will NOT be deleted
   */
  [fileAttribute in NonFunctionPropertyNames<M>]?: boolean;
};

/**
 * Options to pass to delete method
 */
export interface IMFDeleteOptions<M extends IMFModel<M>> {
  deleteOnDeleteFiles?: IMFDeleteOnDeleteFilesOptions<M>;
  cascadeOnDelete?: boolean;
  mode?: MFDeleteMode; // used for override defaultvalue (HARD or @DeletionMode)
}

deleteByReference

deleteByReference(reference: DocumentReference)

Delete a model by its reference

getReferenceFromPath

getReferenceFromPath(path: string)

Get a reference from a compatible path

getSnapshot

getSnapshot(idOrLocation: string | IMFLocation, options?: IMFGetOneOptions)

isCompatible

isCompatible(modelOrReference: M | DocumentReference | CollectionReference)

Check if the model or reference is compatible with this DAO based on its path

User

User Model must implement IMFUserInterface if you want to reference auth user propertties

export class UserModel extends MFModel<UserModel> implements IMFUserInterface {
  @InSubDoc('data/private')
  @AuthUserProperty()
  email: string = null;

  @InSubDoc('data/private')
  @AuthUserProperty()
  phoneNumber: string = null;

  @InSubDoc('data/public')
  @AuthUserProperty()
  photoUrl: string = null;

  @AuthUserProperty()
  displayName: string = null;

  constructor(data: Partial<UserModel>, mustachePath: string, location: Partial<IMFLocation>) {
    super();
    super.initialize(data, mustachePath, location);
  }
}

Usage

Once everything is properly configured you can use standard methods like create, update, delete, get, getList to interact with database. Every async method is based on promises.

Api documentation

You can find more informations on https://moventes.github.io/modelata-node-fire/globals.html

Test

You can test with https://gitlab.com/modelata/test-node-fire