firewand
v0.6.9
Published
Firewand is a modular Firebase utility library for simplifying interactions with Firebase services such as Analytics, Auth, Firestore, Storage, and Stripe payments.
Readme
Firewand
Firewand is a modular Firebase utility library for simplifying interactions with Firebase services such as Analytics, Auth, Firestore, Storage, and Stripe payments. It provides a set of hooks and functions for common Firebase operations and integrates with Stripe for handling payments and subscriptions. Firewand is designed to be used with React applications, Next.js projects, and React Native/Expo applications.
Platform-Specific Features
Authentication Persistence
Firewand automatically handles Firebase Authentication persistence based on the platform:
- React Native: Uses AsyncStorage for persistence through
@react-native-async-storage/async-storage - Web: Uses the default Firebase Auth persistence mechanism
This configuration is handled internally and requires no additional setup, though you must install the peer dependency for React Native:
npm install @react-native-async-storage/async-storage
# or
expo install @react-native-async-storage/async-storageTable of Contents
- Overview
- Installation
- Environment Configuration
- Exported Utilities
- Usage Examples
- React Native/Expo Integration
- FirewandProvider Component
- Contributing
- License
Overview
Firewand centralizes Firebase functionalities into a single library. It exports all necessary Firebase helpers from the main entry point.
Installation
To install Firewand, run:
npm install firewand
# or
yarn add firewandEnvironment Configuration
Web Applications
Create a .env file in your project root with the following variables:
# Firebase Configuration
NEXT_PUBLIC_FIREBASE_API_KEY=your_api_key
NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN=your_project.firebaseapp.com
NEXT_PUBLIC_FIREBASE_PROJECT_ID=your_project_id
NEXT_PUBLIC_FIREBASE_DATABASE_URL=https://your_project.firebaseio.com
NEXT_PUBLIC_FIREBASE_STORAGE_BUCKET=your_project.appspot.com
NEXT_PUBLIC_FIREBASE_MESSAGING_SENDER_ID=your_messaging_sender_id
NEXT_PUBLIC_FIREBASE_APP_ID=your_app_id
NEXT_PUBLIC_FIREBASE_MEASUREMENT_ID=your_measurement_id
NEXT_PUBLIC_FIREBASE_FUNCTIONS_REGION=us-central1
# Firebase Cloud Messaging
NEXT_PUBLIC_VAPID_KEY=your_vapid_key
# Development Configuration
USE_EMULATORS=falseReact Native/Expo
For React Native/Expo projects, use the Expo environment variables in your app.json or .env file:
# Firebase Configuration
EXPO_PUBLIC_FIREBASE_API_KEY=your_api_key
EXPO_PUBLIC_FIREBASE_AUTH_DOMAIN=your_project.firebaseapp.com
EXPO_PUBLIC_FIREBASE_PROJECT_ID=your_project_id
EXPO_PUBLIC_FIREBASE_DATABASE_URL=https://your_project.firebaseio.com
EXPO_PUBLIC_FIREBASE_STORAGE_BUCKET=your_project.appspot.com
EXPO_PUBLIC_FIREBASE_MESSAGING_SENDER_ID=your_messaging_sender_id
EXPO_PUBLIC_FIREBASE_APP_ID=your_app_id
EXPO_PUBLIC_FIREBASE_MEASUREMENT_ID=your_measurement_id
EXPO_PUBLIC_FIREBASE_FUNCTIONS_REGION=us-central1Exported Utilities
Firewand exports the following utilities:
Firebase Core Services
import {
firebaseApp, // Firebase App instance
firestoreDB, // Firestore database instance
firebaseAuth, // Firebase Authentication instance
firebaseStorage, // Firebase Storage instance
firebaseAnalytics, // Firebase Analytics instance
firebaseMessaging, // Firebase Cloud Messaging instance
firebaseFunctions, // Firebase Cloud Functions instance
firebaseDB, // Firebase Realtime Database instance
} from "firewand";Authentication Utilities
import {
useUserSession, // Hook for accessing authenticated user and details
onAuthStateChanged, // Auth state change listener
signInWithGoogle, // Google sign-in method
signOut, // Sign out method
} from "firewand";Firestore Utilities
import {
getCollection, // Get all documents from a collection
getDocument, // Get a specific document
updateDocument, // Update a document
addDocument, // Add a new document
setDocument, // Set document data
setDocumentMerge, // Set document data with merge option
deleteDocument, // Delete a document
onSnapshotWithCollection, // Real-time collection listener
onSnapshotWithDocument, // Real-time document listener
} from "firewand";Stripe Payment Integration
import {
stripePayments, // Initialize Stripe payments
createCheckoutSession, // Create a checkout session
getCurrentUserSubscriptions, // Get user subscriptions
onCurrentUserSubscriptionUpdate, // Listen for subscription updates
getProducts, // Get available products
getPrices, // Get prices for a product
} from "firewand";BTPay Integration
import {
BTPPayments, // BTPay payments client
getBTPPayments, // Initialize BTPay payments
BTPEnvironment, // BTPay environment enum
createPayment, // Create a payment
getCurrentUserPayment, // Get user payment
updatePaymentStatus, // Update payment status
PaymentType, // Payment type enum
Currency, // Currency enum
initiateSimplePayment, // Simple payment helper
} from "firewand";Usage Examples
Basic Firebase App Usage
import { firebaseApp, firestoreDB } from "firewand";
// Use firebaseApp to initialize other services
// Use firestoreDB for database operationsUser Authentication
import { useUserSession } from "firewand";
function App() {
const { user, userDetails } = useUserSession();
return (
<div>
{user ? `Welcome, ${user.email}` : "Sign in"}
{userDetails && <p>User role: {userDetails.role}</p>}
</div>
);
}Firestore Operations
import { getCollection, addDocument } from "firewand";
// Get all documents from a collection
const fetchUsers = async () => {
const users = await getCollection("users");
console.log(users);
};
// Add a new document
const addUser = async (userData) => {
await addDocument("users", userData);
};Analytics Event Logging
import { logAnalyticsEvent } from "firewand";
// Log a custom event
logAnalyticsEvent("button_click", { button_id: "login", page: "home" });Stripe Payments Integration
Firewand provides extensive Stripe integration capabilities for handling subscriptions, payments, and products.
Initialize Stripe Payments
import { stripePayments, firebaseApp } from "firewand";
const payments = stripePayments(firebaseApp);Create a Checkout Session
import { createCheckoutSession, stripePayments, firebaseApp } from "firewand";
const createSubscription = async (priceId) => {
const payments = stripePayments(firebaseApp);
const session = await createCheckoutSession(payments, {
price: priceId,
success_url: window.location.origin + "/success",
cancel_url: window.location.origin + "/cancel",
mode: "subscription",
});
// Redirect to checkout
window.location.assign(session.url);
};Manage Subscriptions
import {
getCurrentUserSubscriptions,
onCurrentUserSubscriptionUpdate,
stripePayments,
firebaseApp,
} from "firewand";
// Get user's subscriptions
const fetchSubscriptions = async () => {
const payments = stripePayments(firebaseApp);
const subscriptions = await getCurrentUserSubscriptions(payments);
return subscriptions;
};
// Listen for subscription changes
const subscribeToSubscriptionChanges = () => {
const payments = stripePayments(firebaseApp);
return onCurrentUserSubscriptionUpdate(
payments,
(snapshot) => {
console.log("Subscriptions updated:", snapshot.subscriptions);
},
(error) => {
console.error("Subscription error:", error);
}
);
};Products and Pricing
import { getProducts, getPrices, stripePayments, firebaseApp } from "firewand";
// Get all products with prices
const fetchProducts = async () => {
const payments = stripePayments(firebaseApp);
const products = await getProducts(payments, { includePrices: true });
return products;
};
// Get prices for a specific product
const fetchPrices = async (productId) => {
const payments = stripePayments(firebaseApp);
const prices = await getPrices(payments, productId);
return prices;
};BTPay Integration Usage
Firewand also provides integration with BTPay for payment processing.
Initialize BTPay
import { getBTPPayments, firebaseApp, BTPEnvironment } from "firewand";
const btpayClient = getBTPPayments(firebaseApp, {
apiKey: "your-btpay-api-key",
environment: BTPEnvironment.SANDBOX,
});Process Payments
import {
initiateSimplePayment,
PaymentType,
Currency,
getBTPPayments,
firebaseApp,
} from "firewand";
const initiatePayment = async (amount) => {
const btpayClient = getBTPPayments(firebaseApp, {
apiKey: "your-btpay-api-key",
environment: BTPEnvironment.SANDBOX,
});
const paymentConfig = {
amount: amount,
currency: Currency.RON,
paymentType: PaymentType.CARD,
description: "Product purchase",
redirectUrl: "https://yourdomain.com/success",
cancelUrl: "https://yourdomain.com/cancel",
};
const result = await initiateSimplePayment(btpayClient, paymentConfig);
// Redirect to payment page
window.location.assign(result.paymentUrl);
};React Native/Expo Integration
React Native Installation
For React Native or Expo projects, install the required dependencies:
# For Expo
expo install firewand firebase @react-native-async-storage/async-storage
# For React Native
npm install firewand firebase @react-native-async-storage/async-storageReact Native Configuration
Set up the Firebase config in your main App component:
import React from "react";
import { FirewandProvider } from "firewand";
import Constants from "expo-constants";
export default function App() {
return (
<FirewandProvider
app="your-app-name"
firebaseConfig={{
apiKey: Constants.expoConfig?.extra?.EXPO_PUBLIC_FIREBASE_API_KEY,
authDomain:
Constants.expoConfig?.extra?.EXPO_PUBLIC_FIREBASE_AUTH_DOMAIN,
projectId: Constants.expoConfig?.extra?.EXPO_PUBLIC_FIREBASE_PROJECT_ID,
storageBucket:
Constants.expoConfig?.extra?.EXPO_PUBLIC_FIREBASE_STORAGE_BUCKET,
messagingSenderId:
Constants.expoConfig?.extra?.EXPO_PUBLIC_FIREBASE_MESSAGING_SENDER_ID,
appId: Constants.expoConfig?.extra?.EXPO_PUBLIC_FIREBASE_APP_ID,
measurementId:
Constants.expoConfig?.extra?.EXPO_PUBLIC_FIREBASE_MEASUREMENT_ID,
}}
>
<MainApp />
</FirewandProvider>
);
}Resolving Common Issues
Authentication Persistence
Firewand automatically handles authentication persistence in React Native using AsyncStorage. Ensure you have @react-native-async-storage/async-storage installed:
expo install @react-native-async-storage/async-storageMetro Bundler Issues
If you encounter "Requiring unknown module 'undefined'" errors with Metro bundler, add this to your metro.config.js:
module.exports = {
resolver: {
extraNodeModules: {
"@react-native-async-storage/async-storage": require.resolve(
"@react-native-async-storage/async-storage"
),
"@firebase/auth/react-native": require.resolve(
"@firebase/auth/react-native"
),
},
},
};FirewandProvider Component
Firewand includes a context provider component for accessing shared state:
import { FirewandProvider, FirewandContext } from "firewand";
function MyApp() {
return (
<FirewandProvider app="your-app-name">
<MainComponent />
</FirewandProvider>
);
}
function MainComponent() {
const { user, userDetails, products, userSubscriptions, isSubscribed } =
useContext(FirewandContext);
// Use the context values
}Contributing
Contributions are welcome. Please refer to the contribution guidelines in the repository for further details.
License
Licensed under the MIT License.
