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

@arbel/firebase-orm

v1.9.43

Published

Firestore Orm

Downloads

175

Readme

Arbel Firebase Orm is an ORM that can run in NodeJS, Browser, Cordova, PhoneGap, Ionic, React Native, NativeScript, Expo, and Electron platforms and can be used with TypeScript and JavaScript (ES5, ES6, ES7, ES8).

Firebase ORM supports only Active Record pattern for now.

Some Arbel Firebase Orm features:

  • supports ActiveRecord
  • allow to specify the Firestore database sturcture as Orm
  • easy way to keep the Firestore nosql sturcture orginazied and easy to managed
  • fetching list and data in real-time (Firesotre feature)
  • store created time and updated time automaticly

And more...

With Firebase ORM your models look like this:

import { Field, BaseModel, Model } from "@arbel/firebase-orm";

@Model({
  reference_path: "websites/:website_id/members",
  path_id: "member_id"
})
export class Member extends BaseModel {
  @Field({
    is_required: true
  })
  public name!: string;

  @Field({
    is_required: true,
    field_name: "photo_url"
  })
  public photoUrl!: string;
}

And your domain logic looks like this:

const member = new Member();
member.name = "Timber";
member.photoUrl = "https://www.example.com/image.png";
member.save()

//To access the data in hierarchy
//Get the website google from the database
const google = await Website.findOne('domain','==','www.google.com');

//Get the linkes under google website
const links = await google.getModel(Link).getAll();

//Using sql to find links inside google model
const list = await google.sql("select * from links where name = 'some link'");


//Get all members
const allMembers = await Member.getAll();

//Get all members with age > 3 and weight > 30
const list = await Member.query().where('age','>','3').where('weight','>','30').get();

//Get all members with age > 3 or age < 3 limit 10
const list = await Member.query().where('age','>','3').orWhere('age','<','3').limit(10).get();

//Get the member tom
const tom = await Member.findOne('firstName','==','Tom');

//Listen to changes in tom data in real time
var unsubscribe = tom.on(()=>{
    //Do something
});

//Get all the list in real time
var unsubscribe = Member.onList((member) => {
    //Do someting with the meber
})
//Get all the list in real time when new meber is addedd
var unsubscribe = Member.onList((member) => {
    //Do someting with the meber
},LIST_EVENTS.ADDEDD)
//Or
var unsubscribe = Member.onModeList({

    /**
     * Listen to add new objects from now
     */
    added?: CallableFunction;

    /**
     * Listen to removed objects
     */
    removed? : CallableFunction

    /**
     * Listen to modify objects
     */
    modified? : CallableFunction

    /**
     * Listen to init loading objects
     */
    init? : CallableFunction
  })

//Kill the listen process
unsubscribe();

Installation

  1. Install the npm package:

    npm install @arbel/firebase-orm firebase rxfire moment --save

TypeScript configuration

Also, make sure you are using TypeScript compiler version 3.3 or greater, and you have enabled the following settings in tsconfig.json:

"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"strictPropertyInitialization" : false,

You may also need to enable es6 in the lib section of compiler options, or install es6-shim from @types.

Quick Start

1.Create global connection

import * as app from "firebase";
import { FirestoreOrmRepository } from "@arbel/firebase-orm";

var firebaseApp = FirestoreOrmRepository.initializeApp(config);

2.Create global path id - (optinal)

import { FirestoreOrmRepository } from "@arbel/firebase-orm";

FirestoreOrmRepository.initGlobalPath("user_id", 50);

3.Create new object

import { Member } from "model/member";

const member = new Member();
member.name = "Timber";
member.photoUrl = "https://www.example.com/image.png";
member.save();

Database Structure

  • only varibales with the decorator @Field will save in the database
  • every model must to include path_id attribute that need to be unique
  • reference_path is the path of the model data inside the dataabse

Text indexing / LIKE Search

1.Add the flag is_text_indexing to @Field decorator

import { Field, BaseModel, Model } from "@arbel/firebase-orm";

@Model({
  reference_path: "websites/:website_id/members",
  path_id: "member_id"
})
export class Member extends BaseModel {
  @Field({
    is_text_indexing: true
  })
  public name!: string;

  @Field({
    is_required: true
  })
  public age!: number;

  @Field({
    is_required: true
  })
  public weight!: number;
}
  1. save new value inside the variable.
  2. use like operator as you need
//Get all members with age > 3 and weight > 30 and name conatin `Dav`
const list = await Member.query()
  .where("age", ">", "3")
  .where("weight", ">", "30")
  .like("name", "%Dav%")
  .get();

Elasticsearch support

1.Add firebase function with onWrite trigger

import * as functions from "firebase-functions";
import { Client } from "@elastic/elasticsearch";

const client = new Client({
  cloud: {
    id: "xxxxxxx",
    username: "xxxxx",
    password: "xxxxxxx"
  }
});

export const elasticsearchProductsSync = functions.firestore
  .document("products/{productId}")
  .onWrite((snap, context) => {
    const productId = context.params.productId;
    const newData = snap.after.data();
    // ...or the previous value before this update
    const previousData = snap.before.data();

    if (newData) {
      newData.id = productId;

      if (!previousData) {
        printLog("create new product - ", productId);
        client
          .create({
            index: "products",
            type: "_doc",
            id: productId,
            body: newData
          })
          .catch(e => {
            var error =
              e.meta && e.meta.body && e.meta.body.error ? e.meta.body : e;
            console.error("Elasticsearch error - ", error);
          });
      } else {
        printLog("update product - ", productId);
        client.transport
          .request({
            method: "POST",
            path: "/products/_doc/" + productId,
            body: newData
          })
          .catch(e => {
            var error =
              e.meta && e.meta.body && e.meta.body.error ? e.meta.body : e;
            console.error("Elasticsearch error - ", error);
          });
      }
    } else {
      printLog("delete product - ", productId);
      client
        .delete({
          index: "products",
          type: "_doc",
          id: productId
        })
        .catch(e => {
          var error =
            e.meta && e.meta.body && e.meta.body.error ? e.meta.body : e;
          console.error("Elasticsearch error - ", error);
        });
    }

    return true;
  });
  1. set global elasticsearch url
FirestoreOrmRepository.initGlobalElasticsearchConnection(
  "https://elasticsearch.com"
);
  1. fetch the data as sql
var result: any = await Product.elasticSql("WHERE qty > 0", 3);
//Total rows
var totalCount = await result.count();
var current = 0;
//Pagination
while (result.next) {
  index++;
  var result = await result.next();
}
  1. or to use binding sql
var result: any = await Product.elasticSql([
  "WHERE name in (:options)  and cost > :cost",
  {
    options: ["a", "b", "c"],
    cost: 9
  }
]);
//Total rows
var totalCount = await result.count();
var current = 0;
//Pagination
while (result.next) {
  index++;
  var result = await result.next();
}

Firebase Storage support

1.Initilize firebase storage connection

var firebaseApp: any = firebase.initializeApp(config.api.firebase);
var storage = firebaseApp.storage();
FirestoreOrmRepository.initGlobalStorage(storage);
  1. Get the storage reference of the wanted field
var product = new Product();
product.name = "test product";
var storageRef = product.getStorageFile("photoUrl");
  1. Upload file
var product = new Product();
await product.getStorageFile("photoUrl").uploadFile(file);
product.save();
  1. Upload file from string
var product = new Product();
await product.getStorageFile("photoUrl").uploadString(file,'base64');
product.save();
  1. Upload file from url (copy file to storage)
var product = new Product();
await product.getStorageFile("photoUrl").uploadFromUrl(url);
product.save();
  1. Get file firebase storage ref
var product = new Product();
var ref = product.getStorageFile("photoUrl").getRef();
  1. Track progress
var product = new Product();
product.name = "test product";
var storageRef = product.getStorageFile("photoUrl");
await storageRef.uploadFromUrl(
  "https://img.example.com/image.jpg",
  function(snapshot: any) {
    // Observe state change events such as progress, pause, and resume
    // Get task progress, including the number of bytes uploaded and the total number of bytes to be uploaded
    var progress = (snapshot.bytesTransferred / snapshot.totalBytes) * 100;
    switch (snapshot.state) {
      case firebase.storage.TaskState.PAUSED: // or 'paused'
        break;
      case firebase.storage.TaskState.RUNNING: // or 'running'
        break;
    }
  },
  function(error: any) {
    // Handle unsuccessful uploads
  },
  function(task: any) {
    // Handle successful uploads on complete
    // For instance, get the download URL: https://firebasestorage.googleapis.com/...
    task.snapshot.ref.getDownloadURL().then(function(downloadURL: any) {
      printLog("File available at", downloadURL);
    });
  }
);
await product.save();