Last active
March 7, 2025 16:46
-
-
Save RodrigoIbarraSanchez/f38137428d4fbe436d78e49e30b77244 to your computer and use it in GitHub Desktop.
RevenueCatProvider
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { createContext, useContext, useEffect, useState } from 'react'; | |
import { Platform } from 'react-native'; | |
import Purchases, { LOG_LEVEL, PurchasesPackage } from 'react-native-purchases'; | |
import { CustomerInfo } from 'react-native-purchases'; | |
// Use your RevenueCat API keys | |
const APIKeys = { | |
apple: '', | |
google: '', | |
}; | |
interface RevenueCatProps { | |
purchasePackage?: (pack: PurchasesPackage) => Promise<void>; | |
restorePermissions?: () => Promise<CustomerInfo>; | |
user: UserState; | |
packages: PurchasesPackage[]; | |
} | |
export interface UserState { | |
coins: number; | |
items: string[]; | |
pro: boolean; | |
} | |
const RevenueCatContext = createContext<RevenueCatProps | null>(null); | |
// Export context for easy usage | |
export const useRevenueCat = () => { | |
return useContext(RevenueCatContext) as RevenueCatProps; | |
}; | |
// Provide RevenueCat functions to our app | |
export const RevenueCatProvider = ({ children }: any) => { | |
const [user, setUser] = useState<UserState>({ coins: 0, items: [], pro: false }); | |
const [packages, setPackages] = useState<PurchasesPackage[]>([]); | |
const [isReady, setIsReady] = useState(false); | |
useEffect(() => { | |
const init = async () => { | |
if (Platform.OS === 'android') { | |
await Purchases.configure({ apiKey: APIKeys.google }); | |
} else { | |
await Purchases.configure({ apiKey: APIKeys.apple }); | |
} | |
setIsReady(true); | |
// Use more logging during debug if want! | |
Purchases.setLogLevel(LOG_LEVEL.DEBUG); | |
// Listen for customer updates | |
Purchases.addCustomerInfoUpdateListener(async (info) => { | |
updateCustomerInformation(info); | |
}); | |
// Load all offerings and the user object with entitlements | |
await loadOfferings(); | |
}; | |
init(); | |
}, []); | |
// Load all offerings a user can (currently) purchase | |
const loadOfferings = async () => { | |
const offerings = await Purchases.getOfferings(); | |
if (offerings.current) { | |
setPackages(offerings.current.availablePackages); | |
} | |
}; | |
// Update user state based on previous purchases | |
const updateCustomerInformation = async (customerInfo: CustomerInfo) => { | |
const newUser: UserState = { coinsa: user.coinsa, items: [], pro: false }; | |
if (customerInfo?.entitlements.active['Epic Wand'] !== undefined) { | |
newUser.items.push(customerInfo?.entitlements.active['Epic Wand'].identifier); | |
} | |
if (customerInfo?.entitlements.active['Magic Boots'] !== undefined) { | |
newUser.items.push(customerInfo?.entitlements.active['Magic Boots'].identifier); | |
} | |
if (customerInfo?.entitlements.active['PRO Features'] !== undefined) { | |
newUser.pro = true; | |
} | |
setUser(newUser); | |
}; | |
// Purchase a package | |
const purchasePackage = async (pack: PurchasesPackage) => { | |
try { | |
await Purchases.purchasePackage(pack); | |
// Directly add our consumable product | |
if (pack.product.identifier === 'rca_299_consume') { | |
setUser({ ...user, coinsa: (user.coinsa += 5) }); | |
} | |
} catch (e: any) { | |
if (!e.userCancelled) { | |
alert(e); | |
} | |
} | |
}; | |
// // Restore previous purchases | |
const restorePermissions = async () => { | |
const customer = await Purchases.restorePurchases(); | |
return customer; | |
}; | |
const value = { | |
restorePermissions, | |
user, | |
packages, | |
purchasePackage | |
}; | |
// Return empty fragment if provider is not ready (Purchase not yet initialised) | |
if (!isReady) return <></>; | |
return <RevenueCatContext.Provider value={value}>{children}</RevenueCatContext.Provider>; | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment