Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Firestore Eloquent Laravel Package

roddy/firestore-eloquent

Bring Eloquent-style modeling to Google Cloud Firestore in Laravel. roddy/firestore-eloquent lets you define models and query Firestore collections with familiar Laravel syntax, making document data feel like native Eloquent records.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture fit — conditional, and narrow. roddy/firestore-eloquent is not an Eloquent replacement; it is an Eloquent-shaped adapter over a document store. Firestore has no joins, no schema, no server-side aggregates worth relying on, and cursor-only pagination. Any domain that leans on relational idioms (reporting queries, whereHas, withCount, offset pagination, migrations as source of truth) will hit a leaky abstraction on day one. Where it does fit: append-heavy or read-by-key domains that need Firestore's native strengths — real-time listeners, offline/mobile SDK parity, per-document security rules, and horizontal write scaling without a DBA. Treat it as a bounded-context persistence adapter, not a default model base class. The value proposition is developer familiarity (Laravel devs ship faster against Firestore), and that value is real but must be budgeted against the abstraction-leak tax.

Integration feasibility — technically straightforward, procedurally unproven. Composer install, service provider auto-discovery, a base model class, and a service-account credential path (GOOGLE_APPLICATION_CREDENTIALS or a config-published JSON) are the expected integration surface, with google/cloud-firestore as the underlying transport. The emulator makes local and CI testing viable. The unknowns are all in the metadata: 16 stars, 0 dependents, a single maintainer, and a release date stamped 2026-10-28 — a future date that is either a metadata artifact or a clock-skew bug and must be verified before anything is pinned. Zero dependents means zero production validation in the wild; we would be an early adopter of an unhardened seam.

Technical risk — high, concentrated in the abstraction seam and vendor concentration.

Risk Severity Note
Leaky Eloquent semantics High Eloquent idioms compile to expensive or unsupported Firestore operations without warning
Single-maintainer bus factor High 16 stars / 0 dependents → likely no external bug-finders; MIT permits fork, but we inherit ownership
Read-cost amplification High Eager-loading/relations become N+1 billable document reads
Missing composite indexes Medium Surface as runtime FAILED_PRECONDITION, not deploy-time failure
Laravel/PHP version drift Medium Constraint matrix unverified against Laravel 11/12 and PHP 8.3+
Auth model inversion Medium Admin SDK bypasses Firestore security rules; authorization must be enforced entirely in Laravel

Key questions (diligence checklist before any code is written).

  1. What Laravel and PHP versions are declared in composer.json, and is there a CI matrix that actually exercises them?
  2. How are relations implemented — separate document reads per relation, or denormalized embedded maps? What is the read-cost profile of with()?
  3. Is pagination cursor-based, or does paginate() silently emulate offsets (a known anti-pattern against Firestore)?
  4. Are batch writes, arrayUnion/increment, and Firestore transactions exposed, or does every save become a full-document overwrite?
  5. Does the package ship emulator configuration and a test-suite pattern, or is testing left to the adopter?
  6. Is there query logging / Telescope integration for observability, or is Firestore a black box in production?
  7. Who maintains it, what is the issue-response history, and is there a stated support horizon?
  8. Does it target Firestore Native mode only, and does it handle Datastore-mode projects at all?

Integration Approach

Stack fit. Reasonable for a Laravel monolith or modular monolith that already runs on Google Cloud and wants Firestore for a specific slice. Poor fit for a team standardized on MySQL/Postgres with BI tooling, SQL-based reporting, or an existing migration-driven schema discipline. Precondition: GCP project, Firestore Native mode, IAM-scoped service account, and a cost-allocation label strategy in place before the first query ships.

Migration path — strangler fig, never a rewrite. Do not port existing Eloquent models. Instead:

  1. Define a repository interface per aggregate in the existing domain layer.
  2. Keep the SQL implementation live; add the Firestore implementation behind the same interface for a single candidate aggregate.
  3. Select candidates by shape: append-only event/log data, per-user preference blobs, real-time notification feeds, mobile-synced state. Reject anything needing cross-entity joins, ad-hoc filtering, or financial-grade multi-row transactions.
  4. Where an aggregate must span both stores, dual-write via a queued job with an idempotency key and a reconciliation job — not a synchronous two-phase write.

Compatibility — the constraint map is the whole conversation. Build this table with the team before estimation; every row is a potential mid-sprint surprise.

Eloquent idiom Firestore reality
join / whereHas Unsupported — denormalize or multi-round-trip
where('x','like','%y%') Unsupported — needs external search (Typesense/Algolia)
orderBy + inequality on different fields Requires composite index; may be rejected
paginate() (offset) Cursor-based only; UI must accept opaque tokens
count() / sum() Per-document reads or maintained counters
Auto-increment id Client-generated IDs; random IDs avoid hotspots
Migrations as schema truth No schema; validation lives in the model/casts
Soft deletes Application-level flag only

Sequencing (one quarter, gated).

  • Week 1–2 — spike. Emulator-only PoC, one aggregate, measure read counts per user journey. Produce a written go/no-go with real numbers.
  • Week 3 — vendor hardening. Pin an exact commit, fork under our org, add CI (Laravel matrix + emulator), and record a fork-ownership decision so bus factor is neutralized on paper, not in a meeting.
  • Week 4–6 — first production slice. Repository interface, dual-write queue, reconciliation job, feature flag.
  • Week 7–8 — observability and cost controls. Per-operation read/write counters, billing budget alerts, latency and error-rate dashboards, index-as-code in Terraform.
  • Week 9+ — evaluate. Second slice only if the first one's cost and defect profile clears the bar.

Operational Impact

Maintenance. The dominant operational cost is not the package's code volume — it is that we will likely own it. A 16-star, single-maintainer, zero-dependent project with an anomalous future release date is a fork-in-waiting. Budget roughly 10–15% of one engineer's time for upstream tracking, security patching of the google/cloud-firestore transitive dependency, and Laravel major-version bumps. Cheap insurance; non-negotiable if the slice becomes load-bearing.

Support. No commercial backing. Google supports Firestore; nobody supports the adapter. Escalation path is GitHub issues, then our own engineers. This is acceptable for a bounded, non-revenue-critical slice and unacceptable for anything on the checkout or auth path. Document the fallback: revert the flag, route reads back to SQL, drain the dual-write queue.

Scaling. Firestore's horizontal scaling is genuine, but three limits bite teams coming from SQL:

  • Per-document write throughput (~1 write/sec sustained). Counters, "likes", and shared state must use sharded/distributed counters, not a single document.
  • Monotonic document IDs create hotspots. Use random IDs, not timestamps or sequences.
  • Cost scales linearly with reads, not with infrastructure. Eloquent habits are expensive habits: a missing with()-equivalent, a polling UI loop, or a dashboard that re-queries per request turns into a visible line item. Read-per-request must become a reviewed metric, the way query count is in SQL shops.

Failure modes.

Mode Trigger Blast radius Mitigation
Missing composite index New query shape at runtime 500s on a specific filter combo Index-as-code; integration tests for every query path
Read-cost runaway N+1 relations, polling Budget breach, latency Per-journey read budget in CI; denormalize deliberately
Quota / rate exhaustion Traffic spike, bulk backfill Project-wide write failures Backfill via rate-limited queue; quota alerts
Credential expiry / IAM drift Rotated service account Total outage of the slice Workload identity, secret rotation tests
Partial batch failure Batch write over limits Silent data loss Idempotency keys + reconciliation job
Type coercion drift Missing casts, floats vs. ints Subtle data corruption Explicit cast coverage; schema tests
Emulator/prod divergence Emulator laxity Green tests, broken prod Contract tests against a staging project

Ramp-up. Superficially fast and deceptively fast. Laravel developers will be productive in a day because the API looks familiar — which is precisely the hazard. The abstraction invites Eloquent muscle memory (with(), paginate(), whereHas()) that produces slow, expensive, or failing Firestore calls with no error at authoring time. Plan an explicit half-day of Firestore-model training (denormalization, cursor pagination, indexes, pricing) before the first slice, and encode the constraint table above into the PR review checklist. The on-call runbook must cover the two failure signatures unique to this adapter: FAILED_PRECONDITION (index) and read-cost spikes (relations).

Bottom line. Approve as a time-boxed, single-slice experiment behind a repository interface and a feature flag, with the fork decision made in week three and cost/read instrumentation shipped before the second slice. Do not approve it as a default model base class, as a path off relational SQL for structured business data, or anywhere the loss of Firestore security rules in favor of in-app authorization is unacceptable. The package is a plausible velocity win; the risk being underwritten is not the code quality, it is the unvalidated 16-star dependency and the Eloquent-idiom tax that only shows up on the invoice.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
socialdept/atp-orm
cboxdk/laravel-assistant-client
socialdept/atp-resolver
socialdept/tenant-domains
tautvydasr/blade-class-names
socialdept/color-scales
maherelgamil/controller
coleus/widgets
coleus/table
coleus/users
coleus/music
coleus/health
coleus/calendar
coleus/notes
coleus/support
coleus/settings
coleus/apps
seampact/laravel
emmyconceptng/laravel-ng-postcode
jjsquady/round-robin