NewYour coding agent can read the release notes before it upgrades.Set up the MCP server →
pub.dev · #5723 most downloaded on pub.dev
Flutter SDK for Koolbase — feature flags, remote config, version enforcement, authentication, storage, database, realtime, OTA updates, and code push for mobile apps.
Last release 3 days ago
05 Oct 2026
Ships on a steady schedule
a new release about every 2 weeks
Most releases are documented
notes for 50 of the last 60 stable releases
Nothing withdrawn
no release was ever pulled
6 months old
104 releases · first in 2026
One column per month.
Storage error mapper switches on lowercase wire codes (path_conflict, quota_exceeded, file_too_large, mime_not_allowed) after the server normalized st
path_conflict,
quota_exceeded, file_too_large, mime_not_allowed) after the server
normalized storage codes to lowercase snake_case. Without this patch,
v6.1.0 customers see generic KoolbaseStorageException instead of the
typed subclass for storage limit errors. No semantic changes beyond
the case match.feat(storage): three new typed exceptions for bucket-limit failures introduced server-side in Storage #2. All extend KoolbaseStorageException so exist
KoolbaseStorageException so existing catch-all blocks continue to
work; catch the specifics to branch on the kind of limit hit.
KoolbaseStorageQuotaExceededException — 409 + QUOTA_EXCEEDED,
thrown when an upload would push the bucket past its
max_size_bytes cap.KoolbaseStorageFileTooLargeException — 413 + FILE_TOO_LARGE,
thrown when a single file exceeds the bucket's
max_file_size_bytes cap.KoolbaseStorageMimeTypeException — 415 + MIME_NOT_ALLOWED,
thrown when an upload's content-type isn't in the bucket's
allowed_mime_types allowlist (supports type/* wildcards).koolbaseStorageError / koolbaseStorageErrorFromResponse)
recognizes the new codes and the new HTTP statuses (413, 415).on KoolbaseStorageException keep working; the new types let callers
surface clearer messages or prompt the user to delete files / pick a
smaller file / pick a different file type.Koolbase.realtime.on / onRecordCreated / onRecordUpdated / onRecordDeleted no longer take a projectId — the project is derived from your session token
Koolbase.realtime.on / onRecordCreated / onRecordUpdated / onRecordDeleted no longer take a projectId — the project is derived from your session token, matching the React Native SDK. Migrate on(projectId: ..., collection: 'x') to on(collection: 'x').KoolbaseStorageClient.upload() is now safe-by-default. Uploads to a
path where an object already exists are rejected with a new
KoolbaseStorageConflictException instead of silently overwriting the
existing object. Pass overwrite: true to opt into the previous
replacing behavior.KoolbaseStorageException subtypes
instead of generic Exception — catching Exception still works but
catching the specific subtypes (or the KoolbaseStorageException base)
gives you cleaner branching.KoolbaseStorageException — base class for all storage failures, mirroring
the KoolbaseDataException pattern from the database layer.KoolbaseStorageConflictException (code: PATH_CONFLICT) — thrown when an
upload would replace an existing object and overwrite: false. Exposes the
colliding path from the server response.KoolbaseStorageNotFoundException, KoolbaseStorageValidationException,
KoolbaseStoragePermissionException — typed exceptions for the other
storage error classes (404, 400, 403). Storage operations now throw these
instead of a generic Exception.koolbaseStorageError(statusCode, body) and
koolbaseStorageErrorFromResponse(res) — code-first response-to-exception
mappers, matching the database layer's pattern.If your app uploads to deterministic paths (e.g. avatars/{user_id}.png)
and relied on the upload silently replacing the previous file:
// Before — silent overwrite
await Koolbase.storage.upload(
bucket: 'avatars',
path: 'me.png',
file: file,
);
// After — explicit overwrite
await Koolbase.storage.upload(
bucket: 'avatars',
path: 'me.png',
file: file,
overwrite: true,
);
If you want a conflict prompt (recommended for user-supplied filenames):
try {
await Koolbase.storage.upload(
bucket: 'documents',
path: filename,
file: file,
);
} on KoolbaseStorageConflictException catch (e) {
final ok = await showConfirm('${e.path} already exists. Overwrite?');
if (ok) {
await Koolbase.storage.upload(
bucket: 'documents',
path: filename,
file: file,
overwrite: true,
);
}
}
If you catch generic exceptions from storage operations, consider
catching KoolbaseStorageException (or specific subtypes) for cleaner
error handling:
try {
await Koolbase.storage.upload(...);
} on KoolbaseStorageConflictException {
// Path already exists — prompt user
} on KoolbaseStorageNotFoundException {
// Bucket missing or deleted
} on KoolbaseStoragePermissionException {
// Caller not authorized
} on KoolbaseStorageException catch (e) {
// Any other storage error
showError(e.message);
}
PATH_CONFLICT 409 support
(shipped alongside this release).Koolbase.realtime.on / onRecordCreated / onRecordUpdated / onRecordDeleted no longer take a projectId — the project is derived from your session token, matching the React Native SDK. Migrate on(projectId: ..., collection: 'x') to on(collection: 'x').KoolbaseStorageClient.upload() is now safe-by-default. Uploads to a
path where an object already exists are rejected with a new
KoolbaseStorageConflictException instead of silently overwriting the
existing object. Pass overwrite: true to opt into the previous
replacing behavior.KoolbaseStorageException subtypes
instead of generic Exception — catching Exception still works but
catching the specific subtypes (or the KoolbaseStorageException base)
gives you cleaner branching.KoolbaseStorageException — base class for all storage failures, mirroring
the KoolbaseDataException pattern from the database layer.KoolbaseStorageConflictException (code: PATH_CONFLICT) — thrown when an
upload would replace an existing object and overwrite: false. Exposes the
colliding path from the server response.KoolbaseStorageNotFoundException, KoolbaseStorageValidationException,
KoolbaseStoragePermissionException — typed exceptions for the other
storage error classes (404, 400, 403). Storage operations now throw these
instead of a generic Exception.koolbaseStorageError(statusCode, body) and
koolbaseStorageErrorFromResponse(res) — code-first response-to-exception
mappers, matching the database layer's pattern.If your app uploads to deterministic paths (e.g. avatars/{user_id}.png)
and relied on the upload silently replacing the previous file:
// Before — silent overwrite
await Koolbase.storage.upload(
bucket: 'avatars',
path: 'me.png',
file: file,
);
// After — explicit overwrite
await Koolbase.storage.upload(
bucket: 'avatars',
path: 'me.png',
file: file,
overwrite: true,
);
If you want a conflict prompt (recommended for user-supplied filenames):
try {
await Koolbase.storage.upload(
bucket: 'documents',
path: filename,
file: file,
);
} on KoolbaseStorageConflictException catch (e) {
final ok = await showConfirm('${e.path} already exists. Overwrite?');
if (ok) {
await Koolbase.storage.upload(
bucket: 'documents',
path: filename,
file: file,
overwrite: true,
);
}
}
If you catch generic exceptions from storage operations, consider
catching KoolbaseStorageException (or specific subtypes) for cleaner
error handling:
try {
await Koolbase.storage.upload(...);
} on KoolbaseStorageConflictException {
// Path already exists — prompt user
} on KoolbaseStorageNotFoundException {
// Bucket missing or deleted
} on KoolbaseStoragePermissionException {
// Caller not authorized
} on KoolbaseStorageException catch (e) {
// Any other storage error
showError(e.message);
}
PATH_CONFLICT 409 support
(shipped alongside this release).setToken was never wired), so it never connected. Switched to the same token-provider model as the other clients; it now authenticates with the user session and streams created/updated/deleted events.KoolbaseRealtimeClient.setToken — dead push-model plumbing that was never wired. The token now flows from the SDK automatically.userId parameter —
identity comes from the active session automatically.Realtime now connects. The client was protocol-correct but was never handed an access token (the push-based setToken was never wired), so it never con
setToken was never wired), so it never connected. Switched to the same token-provider model as the other clients; it now authenticates with the user session and streams created/updated/deleted events.KoolbaseRealtimeClient.setToken — dead push-model plumbing that was never wired. The token now flows from the SDK automatically.Data-plane requests (database, storage, functions, offline sync) authenticate with the signed-in user's access token (Authorization: Bearer) instead o
userId parameter —
identity comes from the active session automatically.Code Push — mandatory bundles. The SDK now honors a bundle's mandatory flag (set from the dashboard or via PATCH /mandatory). When a mandatory bundle
mandatory flag (set from the dashboard or via PATCH /mandatory). When a mandatory bundle is staged for the next launch:
Koolbase.codePush.hasMandatoryUpdate returns true — poll it on resume to gate your UI.onMandatoryUpdate callback on KoolbaseConfig fires immediately with MandatoryUpdateInfo(version, bundleId), so you can prompt the user to restart and apply the required update.Removed the Koolbase.ota client (KoolbaseOtaClient) and its models (OtaCheckResult, OtaProgress, OtaDownloadState). Use Koolbase.codePush for config/f
Koolbase.ota client (KoolbaseOtaClient) and its models
(OtaCheckResult, OtaProgress, OtaDownloadState). Use Koolbase.codePush
for config/flag/directive overrides, or Koolbase Storage for shipping and
reading raw files. This consolidates onto a single bundle client — matching the
React Native SDK and the server, which already use code push exclusively.sign_in_with_apple dependency — it was only used by the removed
KoolbaseAppleAuth. The current signInWithApple({identityToken}) is
library-agnostic, so the SDK no longer pulls it. If your app uses Apple
Sign-In, declare sign_in_with_apple in your own pubspec.yaml.Koolbase.ota client (KoolbaseOtaClient) and its models
(OtaCheckResult, OtaProgress, OtaDownloadState). Use Koolbase.codePush
for config/flag/directive overrides, or Koolbase Storage for shipping and
reading raw files. This consolidates onto a single bundle client — matching the
React Native SDK and the server, which already use code push exclusively.sign_in_with_apple dependency — it was only used by the removed
KoolbaseAppleAuth. The current signInWithApple({identityToken}) is
library-agnostic, so the SDK no longer pulls it. If your app uses Apple
Sign-In, declare sign_in_with_apple in your own pubspec.yaml.code
(with status/message fallback for older servers), retiring brittle message
string-matching.KoolbaseNotFoundException,
KoolbaseValidationException, KoolbasePermissionException,
KoolbaseRateLimitException — plus a shared KoolbaseDataException base.
Database operations now throw these (code-first) instead of a generic
Exception.KoolbaseConflictException now exposes the collided field when the
server reports it.insert no longer queues a server-rejected write (e.g. a unique
conflict) as an offline write — 4xx rejections surface immediately; only
genuine network failures are queued.Auth exceptions are now selected from the server's stable error code (with status/message fallback for older servers), retiring brittle message string
code
(with status/message fallback for older servers), retiring brittle message
string-matching.KoolbaseNotFoundException,
KoolbaseValidationException, KoolbasePermissionException,
KoolbaseRateLimitException — plus a shared KoolbaseDataException base.
Database operations now throw these (code-first) instead of a generic
Exception.KoolbaseConflictException now exposes the collided field when the
server reports it.insert no longer queues a server-rejected write (e.g. a unique
conflict) as an offline write — 4xx rejections surface immediately; only
genuine network failures are queued.Added KoolbaseConflictException, thrown by insert, update, and upsert when a write violates a collection's unique constraint (HTTP 409). Catch it to h
KoolbaseConflictException, thrown by insert, update, and upsert when a write violates a collection's unique constraint (HTTP 409). Catch it to handle duplicates.Docs: document upsert and deleteWhere in the README (no code changes).
upsert and deleteWhere in the README (no code changes).Added Koolbase.db.upsert(collection:, match:, data:) — insert-or-update by a match filter; returns KoolbaseUpsertResult { record, created }. Online-on
Koolbase.db.upsert(collection:, match:, data:) — insert-or-update by a match filter; returns KoolbaseUpsertResult { record, created }. Online-only.Koolbase.db.deleteWhere(collection:, filters:) — bulk delete by filter; returns the number of records deleted. Online-only.Flat record shape. KoolbaseRecord no longer wraps your fields under a data envelope. Your fields are now top-level, with system metadata in a reserved
KoolbaseRecord no longer wraps your fields under a
data envelope. Your fields are now top-level, with system metadata in a
reserved $-prefixed namespace: $id, $createdAt, $updatedAt,
$collection, and $createdBy (when set).KoolbaseRecord.projectId and KoolbaseRecord.collectionId —
internal identifiers are no longer exposed on records.record['field'] — direct field access, shorthand for record.data['field'].record.collection — the record's collection name.populate()) and realtime payloads now use
the same flat $-shape as direct reads.record.projectId / record.collectionId usage — those fields
are gone.record.data['field'] still works; record['field'] is the new shorthand.Replaced the deprecated KoolbaseAppleAuth.signIn() example with the new Koolbase.auth.signInWithApple(identityToken: ..., nonce: ..., fullName: ...) v…
Koolbase.auth.signInWithGoogle(idToken: ..., nonce: ...). Routes to
the server endpoint at /v1/sdk/auth/oauth/google with RS256-only
JWKS verification against Google's certs endpoint, multi-audience
support (iOS / Android / web client IDs configured per environment),
15-minute replay defense, and optional nonce check.auth_exceptions.dart:
GoogleSignInNotConfiguredException, InvalidGoogleTokenException,
GoogleEmailRequiredException. Reuses existing OAuthEmailConflictException
and UserDisabledException.google_sign_in packageimport 'package:google_sign_in/google_sign_in.dart';
final googleUser = await GoogleSignIn().signIn();
final googleAuth = await googleUser?.authentication;
final user = await Koolbase.auth.signInWithGoogle(
idToken: googleAuth!.idToken!,
);
Same as Apple Sign-In (v2.10.0). A new Google identity attaches to an
existing user only when BOTH the Google email AND the existing user's
email are verified, AND emails match (case-insensitive). Otherwise
sign-in either creates a new user (no email collision) or surfaces
OAuthEmailConflictException.
Before users can sign in with Google, configure the provider for your
environment. Run this against your Koolbase project's project_oauth_configs
(dashboard UI for OAuth config lands in a later release):
UPDATE project_oauth_configs
SET google_client_ids = ARRAY[
'<your-ios-client-id>.apps.googleusercontent.com',
'<your-android-client-id>.apps.googleusercontent.com',
'<your-web-client-id>.apps.googleusercontent.com'
],
enabled = true
WHERE environment_id = '<your-env-id>'
AND provider = 'google';
Get the client IDs from Google Cloud Console under Credentials → OAuth 2.0 Client IDs. You'll need one per platform (iOS, Android, web).
Koolbase.auth.signInWithGoogle reference. Google
Sign-In is planned for v2.11.0 — noted explicitly in the OAuth section.KoolbaseAppleAuth.signIn() example with the
new Koolbase.auth.signInWithApple(identityToken: ..., nonce: ..., fullName: ...)
v2.10.0 API using the sign_in_with_apple package.Koolbase.auth.authStateChanges.listen() example.^2.8.0 to ^2.10.0.Nothing published for this version
Nothing published for this version
Nothing published for this version
…concurrent in-flight requests, and honestly deprecates OAuth methods that were never fully wired up on the server side.
A comprehensive overhaul of the authentication module. This release closes seven independent gaps identified by a focused security and reliability audit, adds proper device-attributed session tracking, fixes a refresh-token race that could invalidate concurrent in-flight requests, and honestly deprecates OAuth methods that were never fully wired up on the server side.
Backwards compatible: no breaking changes. Existing code paths continue to work.
Koolbase.auth, calls to Koolbase.functions.invoke() include their access token in the request.ctx.auth — a map with user_id (string or null) and is_authenticated (bool).AUTH_REQUIRED if needed.Sign users in with their phone number — for emerging markets and apps where email isn't the primary identifier.
Sign users in with their phone number — for emerging markets and apps where email isn't the primary identifier.
New methods on Koolbase.auth:
sendOtp({required String phoneNumber}) — sends a 6-digit OTP to an E.164 phone number, returns the expiry timestamp.verifyOtp({required String phoneNumber, required String code}) — verifies the code and signs the user in (creates the account if new). Returns PhoneVerifyResult with an isNewUser flag for routing first-time users to onboarding.linkPhone({required String phoneNumber, required String code}) — links a phone number to an already-authenticated user.New types: OtpSendResult, PhoneVerifyResult.
KoolbaseUser now exposes phoneNumber and phoneVerified fields.
New exceptions: InvalidPhoneNumberException, OtpExpiredException, OtpInvalidException, OtpMaxAttemptsException, OtpRateLimitException, PhoneAlreadyLinkedException, SmsConfigMissingException.
Phone numbers must be in E.164 format (e.g. +233244000000). Configure your SMS provider (Twilio, Africa's Talking, or Hubtel) in the Koolbase dashboard before using.
README update — full feature documentation
Updated drift_flutter to ^0.2.8
Removed deprecated encryptedSharedPreferences parameter
README update — Logic Engine v2 operators
contains — string or list contains value
New operators:
gte — greater than or equalslte — less than or equalscontains — string or list contains valuestarts_with — string starts withends_with — string ends within_list — value is in a listnot_in_list — value is not in a listbetween — numeric value in range [min, max]is_true — value is boolean trueis_false — value is boolean falsenot_exists — value is null or missingAll operators work with AND/OR condition groups.
{
"op": "and",
"conditions": [
{ "op": "gte", "left": { "from": "context.usage" }, "right": 5 },
{ "op": "in_list", "left": { "from": "context.plan" }, "right": ["free", "trial"] }
]
}
README update — added Sign in with Apple section
Added KoolbaseAppleAuth.signIn() — Sign in with Apple for Flutter
KoolbaseAppleAuth.signIn() — Sign in with Apple for FlutterKoolbaseAuthClient.oauthLogin() — unified OAuth login methodAuthApi.oauthLogin() — server-side Apple identity token verificationimport 'package:koolbase_flutter/koolbase_flutter.dart';
final session = await KoolbaseAppleAuth.signIn();
if (session != null) {
print('Signed in: \${session['user']['email']}');
}
Add sign_in_with_apple to your pubspec.yaml and configure your App ID in the Apple Developer portal.
Added KoolbaseMessaging — push notification delivery via FCM
KoolbaseMessaging — push notification delivery via FCMKoolbase.messaging.registerToken(token, platform) — register FCM device token with KoolbaseKoolbase.messaging.send(to, title, body, data) — send push notification to a specific deviceKoolbaseConfig extended with messagingEnabled parameter (default: true)// After obtaining FCM token from firebase_messaging
final fcmToken = await FirebaseMessaging.instance.getToken();
await Koolbase.messaging.registerToken(
token: fcmToken!,
platform: 'android', // or 'ios'
);
// Send to a specific device
await Koolbase.messaging.send(
to: deviceToken,
title: 'Your order is ready',
body: 'Pick up at counter 3',
data: {'order_id': '123'},
);
Add your FCM server key as a project secret named FCM_SERVER_KEY in the Koolbase dashboard.
Updated README — added Code Push, Analytics, Logic Engine sections, comparison table, clearer get started guide
Added KoolbaseAnalyticsClient — event tracking with batched flush
KoolbaseAnalyticsClient — event tracking with batched flushKoolbase.analytics — top-level static accessorKoolbase.analytics.track(eventName, properties) — custom event trackingKoolbase.analytics.screenView(screenName) — screen view trackingKoolbase.analytics.setUserProperty(key, value) — user property managementKoolbase.analytics.identify(userId) — attach authenticated user to eventsKoolbase.analytics.reset() — clear user identity on logoutKoolbaseNavigatorObserver — auto screen tracking via Flutter navigatorapp_open, screen_view, session_endKoolbaseConfig extended with analyticsEnabled parameter (default: true)// Auto screen tracking
MaterialApp(
navigatorObservers: [
KoolbaseNavigatorObserver(client: Koolbase.analytics),
],
)
// Manual tracking
Koolbase.analytics.track('purchase', properties: {
'value': 1200,
'currency': 'GHS',
});
// User identity
Koolbase.analytics.identify(user.id);
Koolbase.analytics.setUserProperty('plan', 'pro');
// Flush on app background
Koolbase.analytics.flush();
Added FlowExecutor — safe, deterministic runtime for evaluating flow node trees
FlowExecutor — safe, deterministic runtime for evaluating flow node treesFlowContext — resolves data from context, config, and flags with dot-notation supportFlowResult — typed result with event name, args, and error stateif, sequence, event (terminal), seteq, neq, gt, lt, and, or, existscontext (app-provided), config (bundle), flags (bundle)BundlePayload extended with flows field — Map<String, dynamic> defaulting to {}KoolbaseDynamicScreen now auto-executes flows on rfw events — if a flow emits a new event, that event is passed to onEvent insteadKoolbase.executeFlow() — top-level static accessorKoolbaseCodePushClient.executeFlow() — direct client accessKoolbaseScreenClient abstract interface extended with executeFlow()// In your bundle's flows.json
{
"on_checkout_tap": {
"type": "if",
"condition": {
"op": "eq",
"left": { "from": "context.plan" },
"right": "free"
},
"then": { "type": "event", "name": "show_upgrade" },
"else": { "type": "event", "name": "go_checkout" }
}
}
// In your app — flows execute automatically from KoolbaseDynamicScreen events
// Or call directly:
final result = Koolbase.executeFlow(
flowId: 'on_checkout_tap',
context: { 'plan': user.plan },
);
if (result.hasEvent) {
Navigator.pushNamed(context, result.eventName!);
}
Added KoolbaseDynamicScreen — drop-in widget that renders server-defined UI from the active bundle
KoolbaseDynamicScreen — drop-in widget that renders server-defined UI from the active bundleKoolbaseCodePushScope — InheritedWidget that wires the code push client into the widget treeKoolbaseRfwWidget — registration type for custom widgets in the rfw runtimeScreenResolver — extracts and caches rfw binaries from the active bundle zipscreens field — map of screenId to .rfw filenameKoolbaseDynamicScreen guarantees: never crash, never block, never surprise — all failures fall back to the local widgetKoolbaseCodePushScope.of(context) moved to didChangeDependencies to avoid initState context restrictions// Wrap your app with KoolbaseCodePushScope
KoolbaseCodePushScope(
client: Koolbase.codePush,
child: MyApp(),
)
// Drop KoolbaseDynamicScreen anywhere
KoolbaseDynamicScreen(
screenId: 'onboarding',
data: {'username': user.name},
onEvent: (name, args) {
if (name == 'get_started') Navigator.pushNamed(context, '/home');
},
fallback: const OnboardingScreen(),
)
Added KoolbaseCodePushClient — full bundle lifecycle management (check, download, verify, cache, activate)
KoolbaseCodePushClient — full bundle lifecycle management (check, download, verify, cache, activate)BundleCache — four-slot cache system (pending, ready, active, archive)BundleVerifier — sha256 checksum verification on every downloadKoolbaseUpdater — background check and download on cold launchBundleLoader — promotes ready bundles to active, handles rollbackRuntimeOverrideEngine — merges bundle config and flags with merge precedence: app defaults → Remote Config → Runtime BundleKoolbase.configInt(), configString(), configDouble(), configBool() — now transparently return bundle values when a bundle is activeKoolbase.isEnabled() — now checks bundle flag overrides firstKoolbaseConfig — new codePushChannel parameter (default: 'stable')Koolbase.codePush — new static accessor for the code push clientAdd codePushChannel to your KoolbaseConfig if you want to subscribe to a specific channel:
await Koolbase.initialize(KoolbaseConfig(
publicKey: 'pk_live_xxx',
baseUrl: 'https://api.koolbase.com',
codePushChannel: 'stable', // new — defaults to 'stable'
));
No other breaking changes.
Nothing published for this version
Functions: Added Dart runtime support
FunctionRuntime enum — FunctionRuntime.deno and FunctionRuntime.dartdeploy() method — deploy functions directly from Flutterinvoke() request body formatDatabase: Offline-first support powered by Drift
Koolbase.db.syncPendingWrites()QueryResult.isFromCache flagDatabase: Added .populate() support on query builder for relational data
.populate() support on query builder for relational data
.populate(['author_id:users', 'category_id:categories'])data with the _id suffix removed (e.g. author_id → author)Nothing published for this version
Full BaaS feature set — auth, database, storage, realtime, functions, feature flags, remote config, version enforcement, OTA updates
OTA Updates: Added Koolbase.ota — over-the-air bundle updates for Flutter apps
Koolbase.ota — over-the-air bundle updates for Flutter appsRealtime: Added Koolbase.realtime — WebSocket realtime SDK
Koolbase.realtime — WebSocket realtime SDK
Koolbase.realtime.on(projectId, collection) — stream of all eventsKoolbase.realtime.onRecordCreated(projectId, collection) — stream of new recordsKoolbase.realtime.onRecordUpdated(projectId, collection) — stream of updated recordsKoolbase.realtime.onRecordDeleted(projectId, collection) — stream of deleted record IDsKoolbase.realtime.connectionState — stream of connection status (true/false)Koolbase.realtime.setToken(token) — set auth token for subscriptionsDatabase: Added Koolbase.db — database SDK
Koolbase.db — database SDK
Koolbase.db.collection('name').get() — query records with fluent builderKoolbase.db.collection('name').where('field', isEqualTo: value).limit(20).get()Koolbase.db.insert(collection: 'name', data: {...}) — insert recordsKoolbase.db.doc(id).get() — fetch single recordKoolbase.db.doc(id).update({...}) — patch record fieldsKoolbase.db.doc(id).delete() — soft delete recordKoolbaseRecord, KoolbaseCollection, QueryResult modelsStorage: Added Koolbase.storage — file storage SDK
Koolbase.storage — file storage SDK
upload() — upload files directly to Cloudflare R2 via presigned URLsgetDownloadUrl() — get signed download URLs for private filesdelete() — delete files from storageKoolbaseObject, KoolbaseBucket, UploadResult modelsAuth: Added Koolbase.auth — full authentication SDK
Koolbase.auth — full authentication SDK
signUp, login, logout, forgotPassword, resetPassword, verifyEmailcurrentUser, isAuthenticated, authStateChanges streamflutter_secure_storageKoolbaseUser, AuthSession modelsKoolbaseAuthException and typed exceptionsFeature flags with rollout percentages and kill switches
Your coding agent can read these notes before it upgrades. Set up the MCP server →