
Security News
AGENTS.md Gains Traction as an Open Format for AI Coding Agents
AGENTS.md is a fast-growing open format giving AI coding agents a shared, predictable way to understand project setup, style, and workflows.
@dataql/firebase-adapter
Advanced tools
Migrate from Firebase/Firestore to DataQL with zero API changes. This adapter provides a Firebase-compatible API that runs on DataQL with automatic scaling, caching, and offline support.
npm install @dataql/core @dataql/firebase-adapter
import { initializeApp, getFirestore } from "@dataql/firebase-adapter";
// Initialize Firebase app with DataQL
const firebaseConfig = {
apiKey: "your-api-key",
authDomain: "your-project.firebaseapp.com",
projectId: "your-project",
storageBucket: "your-project.appspot.com",
messagingSenderId: "123456789",
appId: "1:123456789:web:abcdef123456",
};
const app = initializeApp(firebaseConfig, {
appToken: "your-app-token", // Required for DataQL authentication
env: "prod", // Environment: 'dev' or 'prod'
dbName: "your_app_db", // Database name for data isolation
});
const db = getFirestore(app);
// Use familiar Firestore syntax - all operations powered by DataQL
const usersRef = db.collection("users");
// Add a document
const docRef = await usersRef.add({
name: "John Doe",
email: "john@example.com",
age: 30,
active: true,
});
console.log("Document written with ID: ", docRef.id);
// Query documents
const snapshot = await usersRef
.where("active", "==", true)
.where("age", ">=", 18)
.orderBy("name")
.limit(10)
.get();
snapshot.forEach((doc) => {
console.log(doc.id, " => ", doc.data());
});
// Real-time listener
const unsubscribe = usersRef.onSnapshot((snapshot) => {
snapshot.forEach((doc) => {
console.log("User:", doc.data());
});
});
// Clean up listener
unsubscribe();
const app = initializeApp(firebaseConfig, {
appToken: "your-app-token", // Required - authentication for DataQL
env: "prod", // Optional - 'dev' or 'prod' (default: 'prod')
devPrefix: "dev_", // Optional - prefix for dev environment collections
dbName: "your_app_db", // Optional - database name for data isolation
customConnection: undefined, // Optional - for custom integrations
});
While maintaining 100% Firebase API compatibility, you get DataQL's enhanced capabilities:
Replace imports:
// Before
import { initializeApp } from "firebase/app";
import { getFirestore } from "firebase/firestore";
// After
import { initializeApp, getFirestore } from "@dataql/firebase-adapter";
Update app initialization:
// Before - Direct Firebase connection
const app = initializeApp(firebaseConfig);
// After - DataQL authentication
const app = initializeApp(firebaseConfig, {
appToken: "your-app-token", // Required for DataQL authentication
dbName: "your_app_db", // Your database name
});
Your Firestore code works exactly the same:
// This works exactly the same - but now powered by DataQL
const db = getFirestore(app);
const snapshot = await db.collection("users").get();
initializeApp(config, options)
- Initialize Firebase appgetFirestore(app)
- Get Firestore instancecollection(path)
- Get collection referencedoc(path)
- Get document reference.add(data)
- Add document to collection.doc(id)
- Get document by ID.where(field, operator, value)
- Filter documents.orderBy(field, direction)
- Sort documents.limit(count)
- Limit number of results.get()
- Execute query and get snapshot.onSnapshot(callback)
- Real-time listener.get()
- Get document snapshot.set(data, options)
- Set document data.update(data)
- Update document fields.delete()
- Delete document.onSnapshot(callback)
- Real-time document listener==
- Equal to!=
- Not equal to<
- Less than<=
- Less than or equal to>
- Greater than>=
- Greater than or equal toarray-contains
- Array contains valuein
- Field value is in arrayarray-contains-any
- Array contains any of the valuesDocumentSnapshot
with .data()
, .get()
, .exists
QuerySnapshot
with .docs
, .size
, .empty
, .forEach()
QueryDocumentSnapshot
with .data()
, .get()
WriteResult
with .writeTime
While maintaining Firebase compatibility, you also get DataQL's additional features:
createUnique()
method to prevent duplicatesFull TypeScript support with inferred types:
import {
initializeApp,
getFirestore,
DocumentData,
} from "@dataql/firebase-adapter";
interface User {
name: string;
email: string;
age?: number;
active: boolean;
createdAt?: string;
}
const app = initializeApp(firebaseConfig, options);
const db = getFirestore(app);
// Type-safe operations
const usersRef = db.collection("users");
const userDoc = await usersRef.doc("user123").get();
if (userDoc.exists) {
const userData = userDoc.data() as User;
console.log("User:", userData.name);
}
// Typed queries
const activeUsers = await usersRef.where("active", "==", true).get();
activeUsers.forEach((doc) => {
const user = doc.data() as User;
console.log("Active user:", user.name);
});
Real-time features work just like Firebase:
// Collection listener
const unsubscribe = db.collection("messages").onSnapshot((snapshot) => {
snapshot.docChanges().forEach((change) => {
if (change.type === "added") {
console.log("New message:", change.doc.data());
} else if (change.type === "modified") {
console.log("Modified message:", change.doc.data());
} else if (change.type === "removed") {
console.log("Removed message:", change.doc.data());
}
});
});
// Document listener
const docUnsubscribe = db.doc("users/user123").onSnapshot((doc) => {
if (doc.exists) {
console.log("Current data:", doc.data());
} else {
console.log("Document does not exist");
}
});
// Cleanup
unsubscribe();
docUnsubscribe();
Complex queries with multiple filters and ordering:
// Complex filtering
const posts = await db
.collection("posts")
.where("published", "==", true)
.where("category", "in", ["tech", "science"])
.where("likes", ">=", 10)
.orderBy("createdAt", "desc")
.limit(20)
.get();
posts.forEach((doc) => {
console.log("Post:", doc.data());
});
// Array queries
const usersByTags = await db
.collection("users")
.where("tags", "array-contains", "developer")
.get();
const usersByMultipleTags = await db
.collection("users")
.where("tags", "array-contains-any", ["developer", "designer"])
.get();
// Compound queries
const recentActiveUsers = await db
.collection("users")
.where("active", "==", true)
.where("lastLoginAt", ">=", "2024-01-01")
.orderBy("lastLoginAt", "desc")
.limit(50)
.get();
Standard Firestore document operations:
const userRef = db.collection("users").doc("user123");
// Create/set document
await userRef.set({
name: "John Doe",
email: "john@example.com",
active: true,
});
// Update specific fields
await userRef.update({
name: "John Smith",
lastUpdated: new Date(),
});
// Merge data with existing document
await userRef.set(
{
preferences: {
theme: "dark",
notifications: true,
},
},
{ merge: true }
);
// Get document
const doc = await userRef.get();
if (doc.exists) {
console.log("User data:", doc.data());
} else {
console.log("User not found");
}
// Delete document
await userRef.delete();
Standard Firebase error handling:
try {
const doc = await db.collection("users").doc("user123").get();
if (doc.exists) {
console.log("User:", doc.data());
} else {
console.log("User not found");
}
} catch (error) {
console.error("Error getting user:", error);
}
// Handling write operations
try {
await db.collection("users").add({
name: "Jane Doe",
email: "jane@example.com",
});
console.log("User created successfully");
} catch (error) {
console.error("Error creating user:", error);
}
Some advanced Firebase features are not yet supported:
startAt
, endAt
methods are simplifiedIf you need these features, please open an issue.
const db = getFirestore(app);
// Create
const newUserRef = await db.collection("users").add({
name: "Alice Johnson",
email: "alice@example.com",
role: "admin",
createdAt: new Date(),
});
// Read
const userSnapshot = await db
.collection("users")
.where("role", "==", "admin")
.get();
userSnapshot.forEach((doc) => {
console.log("Admin user:", doc.data());
});
// Update
await db.collection("users").doc(newUserRef.id).update({
name: "Alice Smith",
updatedAt: new Date(),
});
// Delete
await db.collection("users").doc(newUserRef.id).delete();
// Listen for new messages
const messagesRef = db.collection("messages");
const unsubscribe = messagesRef
.orderBy("timestamp", "desc")
.limit(50)
.onSnapshot((snapshot) => {
snapshot.forEach((doc) => {
const message = doc.data();
addMessageToUI(message);
});
});
// Send a message
async function sendMessage(text: string, userId: string) {
try {
await messagesRef.add({
text,
userId,
timestamp: new Date(),
reactions: [],
});
} catch (error) {
console.error("Failed to send message:", error);
}
}
// Cleanup
function cleanup() {
unsubscribe();
}
// Query products by category with pagination
async function getProducts(category: string, limit: number = 20) {
const productsRef = db.collection("products");
const snapshot = await productsRef
.where("category", "==", category)
.where("inStock", "==", true)
.orderBy("price", "asc")
.limit(limit)
.get();
return snapshot.docs.map((doc) => ({
id: doc.id,
...doc.data(),
}));
}
// Search products by tags
async function searchProducts(tags: string[]) {
const productsRef = db.collection("products");
const snapshot = await productsRef
.where("tags", "array-contains-any", tags)
.where("available", "==", true)
.get();
return snapshot.docs.map((doc) => ({
id: doc.id,
...doc.data(),
}));
}
// Update product inventory
async function updateInventory(productId: string, quantity: number) {
const productRef = db.collection("products").doc(productId);
await productRef.update({
inventory: quantity,
inStock: quantity > 0,
lastUpdated: new Date(),
});
}
MIT
FAQs
Firebase adapter for DataQL with zero API changes
The npm package @dataql/firebase-adapter receives a total of 0 weekly downloads. As such, @dataql/firebase-adapter popularity was classified as not popular.
We found that @dataql/firebase-adapter demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
AGENTS.md is a fast-growing open format giving AI coding agents a shared, predictable way to understand project setup, style, and workflows.
Security News
/Research
Malicious npm package impersonates Nodemailer and drains wallets by hijacking crypto transactions across multiple blockchains.
Security News
This episode explores the hard problem of reachability analysis, from static analysis limits to handling dynamic languages and massive dependency trees.