{"id":42756,"library":"firesnap","title":"Firesnap","description":"Firesnap is an ORM/ODM for Google Firestore, inspired by Mongoose, providing data validation, population of related data, and lifecycle hooks (save/delete callbacks). Current stable version is 1.0.14. It supports both TypeScript (with decorators) and JavaScript (with static schema). Key differentiators: decorator-based model definition, built-in validation, and Firestore-specific query operators ($eq, $gt, etc.). Release cadence is irregular; maintained primarily by a single developer. Not officially stable or production-ready (version < 1.0).","status":"active","version":"1.0.14","language":"javascript","source_language":"en","source_url":"https://github.com/EliotBrown/firesnap","tags":["javascript","firebase","firestore","orm","odm","mongoose","typescript"],"install":[{"cmd":"npm install firesnap","lang":"bash","label":"npm"},{"cmd":"yarn add firesnap","lang":"bash","label":"yarn"},{"cmd":"pnpm add firesnap","lang":"bash","label":"pnpm"}],"dependencies":[{"reason":"Firestore database client - mandatory peer dependency","package":"firebase-admin","optional":false}],"imports":[{"note":"Named export in ESM; CommonJS use { Firesnap }","wrong":"const Firesnap = require('firesnap').default","symbol":"Firesnap","correct":"import { Firesnap } from 'firesnap'"},{"note":"Same pattern for both ESM and CJS","wrong":"const Model = require('firesnap').Model","symbol":"Model","correct":"import { Model } from 'firesnap'"},{"note":"Works with require due to named export","wrong":"const Field = require('firesnap').Field","symbol":"Field","correct":"import { Field } from 'firesnap'"},{"note":"Used in class definitions, not a constructor","wrong":"","symbol":"Collection","correct":"import { Collection } from 'firesnap'"}],"quickstart":{"code":"import * as admin from 'firebase-admin';\nimport { Firesnap, Model, Field, Collection } from 'firesnap';\n\nconst serviceAccount = require('./serviceAccountKey.json');\nadmin.initializeApp({\n  credential: admin.credential.cert(serviceAccount),\n});\nFiresnap.initialize(admin.firestore());\n\nclass Post extends Model {\n  @Field({ required: true })\n  title: string;\n\n  @Field()\n  created = Date.now;\n\n  @Collection(Comment)\n  comments: Comment[];\n}\n\nconst post = new Post({ title: 'Hello' });\nawait post.save();\nconst retrieved = await Post.doc('some-id').get();\nconsole.log(retrieved.title);","lang":"typescript","description":"Shows initialization with Firebase Admin SDK, model definition using decorators, and basic CRUD operations."},"warnings":[{"fix":"Set 'experimentalDecorators': true and 'emitDecoratorMetadata': true in compilerOptions","message":"TypeScript requires experimentalDecorators and emitDecoratorMetadata in tsconfig.json","severity":"gotcha","affected_versions":">=0.0.0"},{"fix":"Call Firesnap.initialize(admin.firestore()) at app startup","message":"Firesnap must be initialized before any model operations; calling Model methods before initialization throws","severity":"gotcha","affected_versions":">=0.0.0"},{"fix":"Pin to exact version and expect breaking changes on minor updates","message":"Version 1.0.x is pre-1.0; API may change without semver notice","severity":"deprecated","affected_versions":"<1.0.0"},{"fix":"Use await Post.doc('id').get() instead of just Post.doc('id')","message":"Model.doc() returns a reference, not a document; must call .get() to retrieve data","severity":"gotcha","affected_versions":">=0.0.0"}],"env_vars":null,"search_vec":"'1.0':78 '1.0.14':28 'base':44 'built':48 'built-in':47 'cadenc':61 'callback':23 'current':24 'data':13,18 'decor':34,43 'decorator-bas':42 'definit':46 'develop':69 'differenti':41 'eq':57 'etc':59 'firebas':80 'firesnap':1,2 'firestor':8,53,81 'firestore-specif':52 'googl':7 'gt':58 'hook':21 'inspir':9 'irregular':63 'javascript':36,79 'key':40 'lifecycl':20 'maintain':64 'model':45 'mongoos':11,84 'odm':83 'offici':71 'oper':56 'orm':82 'orm/odm':5 'popul':15 'primarili':65 'product':75 'production-readi':74 'provid':12 'queri':55 'readi':76 'relat':17 'releas':60 'save/delete':22 'schema':39 'singl':68 'specif':54 'stabl':25,72 'static':38 'support':30 'typescript':32,85 'valid':14,50 'version':26,77","created_at":"2026-06-05T16:56:30.528087+00:00","updated_at":"2026-06-05T16:56:30.528087+00:00","problems":[{"fix":"Add 'experimentalDecorators': true and 'emitDecoratorMetadata': true to tsconfig.json","cause":"Missing tsconfig.json compiler options","error":"Cannot find name 'decorators' or 'experimentalDecorators' error"},{"fix":"Call Firesnap.initialize(admin.firestore()) after admin.initializeApp()","cause":"Forgot to call Firesnap.initialize() before using models","error":"Firesnap is not initialized"},{"fix":"Ensure class extends Model and import { Model } from 'firesnap'","cause":"Model not properly extended or firesnap not imported correctly","error":"TypeError: Post.doc is not a function"},{"fix":"Use const docRef = Post.doc('id'); const doc = await docRef.get();","cause":"Calling doc() without a valid document ID or before get()","error":"Cannot read property 'id' of undefined"}],"ecosystem":"npm","meta_description":null,"install_score":null,"quickstart_score":null,"quickstart_tag":null,"pypi_latest":null,"cli_name":null,"cli_version":null,"type":"library","homepage":"https://github.com/EliotBrown/firesnap#readme","github":"https://github.com/EliotBrown/firesnap","docs":null,"changelog":null,"pypi":null,"npm":"firesnap","openapi_spec":null,"status_page":null,"smithery":null,"categories":["database"],"base_url":null,"auth_type":null,"provenance":{"verified_status":null,"verified_at":null,"last_verified":"2026-06-05","next_check":"2026-09-03","install_tag":null}}