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 🙏

© 2026 – Pkg Stats / Ryan Hefner

rn-sql-connect

v0.3.1

Published

React Native native SDK for Firebase SQL Connect (Data Connect). Wraps the Android and Apple native SDKs instead of running the JS web SDK inside React Native.

Readme

rn-sql-connect

React Native SDK for Firebase SQL Connect (Data Connect) built on the native Android and Apple SDKs, not on the JavaScript web SDK.

Status: pre-release, working end to end on both platforms: 16 of 16 smoke steps pass on an Android emulator and an iOS simulator against the Data Connect emulator, including auth-gated operations and every scalar type. See Verification status.

Why

Running firebase/data-connect inside React Native works, but it costs you:

| With the web SDK in RN | With rn-sql-connect | | --- | --- | | A second Firebase JS app next to @react-native-firebase | One Firebase app | | A custom-token bridge so @auth(USER) operations have an identity | Auth token attached automatically by the native SDK | | An App Check CustomProvider relaying the native token | App Check token attached automatically | | In-memory cache only, no expiry | Persistent cache with maxAge and three fetch policies | | firebase in your JS bundle | No JS Firebase dependency |

Requirements

| Requirement | Minimum | Why | | --- | --- | --- | | React Native | 0.85 | spm_dependency and stable codegen event emitters | | Architecture | New Architecture | This package ships a TurboModule only | | @react-native-firebase/app | 24.0.0 | Firebase is resolved through CocoaPods, which every version of react-native-firebase supports. Verified on a real device against 24.1.1 (Firebase 12.10.0) and 26.1.0 (Firebase 12.17.0) | | iOS Podfile | $RNFirebaseDisableSPM = true | See below | | iOS deployment target | 15.0 | Required by data-connect-ios-sdk | | Android minSdk | 23 | Required by Firebase BoM 34 | | firebase-tools (codegen only) | 15.14.0 | Realtime-capable SDK generation |

iOS needs react-native-firebase in CocoaPods mode. In short:

  • FirebaseDataConnect is distributed through Swift Package Manager only.
  • SwiftPM links a private copy of FirebaseCore into every framework that depends on it, so Data Connect would not see the Firebase instance react-native-firebase configured, and @auth(USER) operations would fail.
  • So the Apple SDK is vendored into this package and Firebase comes from CocoaPods, the same copy react-native-firebase uses.
  • pod install refuses to proceed if that is not the case, rather than letting it fail at runtime.

Full reasoning in iOS architecture, confirmed upstream in invertase/react-native-firebase#9140.

Documentation

Full docs live in docs/, grouped by what you are doing.

| | | | --- | --- | | Guides, in order | Getting started, queries and mutations, caching, realtime, auth, error handling, Code generation, migrating from the web SDK, testing your app | | Reference | API, configuration, error codes, data types | | When it breaks | Troubleshooting, which opens with a symptom index | | Internals | Bridge design, iOS architecture | | Contributing | Local testing |

Install

npm install rn-sql-connect
cd ios && pod install
# ios/Podfile, before any target block
$RNFirebaseDisableSPM = true
$RNFirebaseAsStaticFramework = true

On Apple platforms, call FirebaseApp.configure() in your AppDelegate as react-native-firebase requires. Without it every call fails with not-configured.

Usage

import { getSqlConnect, executeQuery, executeMutation, subscribe, QueryFetchPolicy } from 'rn-sql-connect'

const dc = getSqlConnect(
  { connector: 'example', location: 'asia-southeast1', serviceId: 'example' },
  { cacheSettings: { storage: 'persistent', maxAge: '5m' } },
)

// One shot
const { data, source } = await executeQuery<ListMoviesData>(dc, 'ListMoviesByGenre', { genre: 'Sci-Fi' })
console.log(source) // 'cache' or 'server'

// Never serve a stale read
await executeQuery(dc, 'GetConfig', undefined, { fetchPolicy: QueryFetchPolicy.SERVER_ONLY })

// Mutation
await executeMutation(dc, 'CreateMovie', { title: 'Dune', genre: 'Sci-Fi' })

// Realtime
const unsubscribe = subscribe(dc, 'GetMovieById', { id }, {
  next: result => setMovie(result.data.movie),
  error: error => console.warn(error.code, error.message),
})

React hook:

import { useSqlConnectQuery } from 'rn-sql-connect/react'

const { data, loading, error, source, refetch } = useSqlConnectQuery(dc, 'ListMoviesByGenre', { genre: 'Sci-Fi' }, {
  subscribe: true,
})

Cache policy, and one trap worth knowing

maxAge defaults to 0, which means responses are cached but every PREFER_CACHE call still revalidates against the server. Raising maxAge is what makes cached reads actually serve. So:

  • A screen where stale data is only a cosmetic delay: raise maxAge.
  • Anything where a stale read is a bug (feature flags, config versions, balances): pass SERVER_ONLY explicitly. Do not rely on maxAge staying 0 forever.

The cache lives on disk and nothing clears it automatically - not terminate(), not signing out. Both SDKs scope cached rows by uid, so the next person to sign in cannot read the previous one's data, but that data is still on the device. Erase it when a session ends:

import { clearCache } from 'rn-sql-connect'

await signOut(getAuth())
await clearCache() // deletes every Data Connect cache file for this app

Auth and App Check

Nothing to wire up. The native SDKs read the current user and the App Check token from the same FirebaseApp. @auth(USER) operations work as soon as the user is signed in through @react-native-firebase/auth, verified on both platforms.

One Data Connect rule worth knowing before you debug it the hard way: @auth(level: USER) rejects anonymous users. A user signed in with signInAnonymously gets unauthenticated with debug_details: "@auth(level: USER) doesn't allow anonymous users". Use @auth(level: USER_ANON) on the operation if anonymous callers should be allowed.

If a USER operation returns unauthorized, check what native sees:

import { getDiagnostics } from 'rn-sql-connect'
console.log(await getDiagnostics(dc)) // { hasCurrentUser, uid, appCheckConfigured, activeSubscriptions, ... }

Emulator

import { connectSqlConnectEmulator } from 'rn-sql-connect'
connectSqlConnectEmulator(dc, { port: 9399 }) // must run before the first operation
firebase emulators:start --only dataconnect,auth

Typed SDK generation

npx rn-sql-connect-codegen --in vendor/dataconnect-generated/example --out src/dataconnect/example

The generator reads the JavaScript SDK produced by firebase dataconnect:sdk:generate and emits TypeScript wrappers with the same function names, so migrating a call site is only a change of import path:

-import { listMoviesByGenre } from '@dataconnect/example'
+import { listMoviesByGenre } from '@/src/dataconnect/example'

Every query also gets a subscribeXxx helper. The emitted code has no dependency on the firebase package, and the generator refuses to emit anything that still references web SDK types.

Realtime requirements

subscribe() only pushes updates when the server is able to signal a refresh:

  • Single entity lookups by primary key get refresh signals implicitly.
  • Anything else (lists, filtered queries) needs @refresh(onMutationExecuted: ...) on the operation, with a CEL condition narrow enough to avoid refreshing on unrelated writes.

Operations live on the server, so this is a schema change, not a client change.

Error handling

import { SqlConnectError } from 'rn-sql-connect'

try {
  await executeQuery(dc, 'GetProfile')
} catch (error) {
  if (error instanceof SqlConnectError) {
    error.code // 'unauthenticated' | 'unauthorized' | 'not-found' | 'invalid-argument'
               // | 'partial-error' | 'unavailable' | 'cancelled' | 'not-configured'
               // | 'internal' | 'unknown'
    error.graphQLErrors // [{ message, path }]
    error.partialData   // set when code === 'partial-error'
    error.nativeCode    // original platform error, for bug reports
  }
}

partial-error means the server returned data and errors. Whether that partial data is usable is your call, so it is surfaced rather than silently dropped.

Debugging

globalThis.RNSqlConnectDebug = true // logs every native call and its result

Verification status

| Layer | State | | --- | --- | | JavaScript core, hook, error mapping, subscription dedupe | Unit tested (77 tests) | | Code generator | Unit tested, plus generated from three real connectors (6, 55 and 96 operations) and compiled | | Android Kotlin | 18 of 18 smoke steps pass on an Android emulator against the Data Connect emulator | | iOS Swift and TurboModule shim | 18 of 18 smoke steps pass on an iOS simulator, with the Apple SDK vendored and Firebase from CocoaPods |

Each smoke run covers, on a real device, against a real emulator:

  • a mutation, a server read, an on-disk cache read returning source: cache
  • a realtime subscription reacting to a mutation from the same client
  • every scalar the wire format carries: Int64, UUID, Timestamp, Date, Float, Boolean, String, Int, lists of String and Int, and a nested Any containing a null
  • auth: an @auth(level: USER) operation refused while signed out, then accepted after signing in with @react-native-firebase/auth, with native reporting the same uid. No token plumbing anywhere
  • native diagnostics and error-code mapping agreeing across both platforms
  • clearCache: three cache files erased and a second call reporting 0, with the databases directory verified empty afterwards

Still unproven: App Check (implemented, not exercised), a secondary Firebase app, Vector and enum scalars, and true offline behaviour with the network off.

One measured platform difference, documented rather than papered over: straight after clearCache, a CACHE_ONLY read misses on iOS but is still served on Android, whose open SQLite handle keeps reading the unlinked file until the process exits. The files are gone from disk on both.

See Local testing for how to reproduce any of this in a few minutes.

On iOS the Apple Data Connect SDK is vendored rather than pulled through Swift Package Manager, because SwiftPM would give this package a private copy of FirebaseCore and Data Connect would never see the signed-in user. That is an upstream packaging property, confirmed in #9140. The vendored copy is pinned and CI fails if it drifts (npm run vendor:check).

License

Apache-2.0