@umituz/react-native-subscription 2.14.22 → 2.14.24

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@umituz/react-native-subscription",
3
- "version": "2.14.22",
3
+ "version": "2.14.24",
4
4
  "description": "Complete subscription management with RevenueCat, paywall UI, and credits system for React Native apps",
5
5
  "main": "./src/index.ts",
6
6
  "types": "./src/index.ts",
@@ -9,19 +9,69 @@ import { configureCreditsRepository } from "../repositories/CreditsRepositoryPro
9
9
  import { SubscriptionManager } from "../../revenuecat/infrastructure/managers/SubscriptionManager";
10
10
  import { configureAuthProvider } from "../../presentation/hooks/useAuthAwarePurchase";
11
11
 
12
+ export interface FirebaseAuthLike {
13
+ currentUser: { uid: string; isAnonymous: boolean } | null;
14
+ onAuthStateChanged: (callback: (user: { uid: string; isAnonymous: boolean } | null) => void) => () => void;
15
+ }
16
+
12
17
  export interface SubscriptionInitConfig {
13
18
  apiKey: string;
14
19
  testStoreKey?: string;
15
20
  entitlementId: string;
16
21
  credits: CreditsConfig;
17
22
  getAnonymousUserId: () => Promise<string>;
18
- getFirebaseAuth: () => { currentUser: { isAnonymous: boolean } | null } | null;
23
+ getFirebaseAuth: () => FirebaseAuthLike | null;
19
24
  showAuthModal: () => void;
20
25
  onCreditsUpdated?: (userId: string) => void;
21
26
  onCreditRenewal?: (userId: string, productId: string, renewalId: string) => Promise<void>;
22
27
  timeoutMs?: number;
28
+ authStateTimeoutMs?: number;
23
29
  }
24
30
 
31
+ /**
32
+ * Wait for Firebase Auth state to be ready
33
+ * This prevents unnecessary logIn calls that trigger Apple Sign In dialog
34
+ */
35
+ const waitForAuthState = async (
36
+ getFirebaseAuth: () => FirebaseAuthLike | null,
37
+ timeoutMs: number
38
+ ): Promise<string | undefined> => {
39
+ const auth = getFirebaseAuth();
40
+ if (!auth) return undefined;
41
+
42
+ // If user already available, return immediately
43
+ if (auth.currentUser) {
44
+ if (__DEV__) {
45
+ console.log("[Subscription] User already available:", auth.currentUser.uid);
46
+ }
47
+ return auth.currentUser.uid;
48
+ }
49
+
50
+ // Wait for auth state to settle
51
+ return new Promise<string | undefined>((resolve) => {
52
+ const unsubscribe = auth.onAuthStateChanged((user) => {
53
+ unsubscribe();
54
+ if (__DEV__) {
55
+ console.log("[Subscription] Auth state ready:", {
56
+ hasUser: !!user,
57
+ userId: user?.uid ?? "anonymous",
58
+ isAnonymous: user?.isAnonymous ?? true,
59
+ });
60
+ }
61
+ resolve(user?.uid || undefined);
62
+ });
63
+
64
+ // Timeout fallback - don't wait forever
65
+ setTimeout(() => {
66
+ unsubscribe();
67
+ if (__DEV__) {
68
+ console.log("[Subscription] Auth state timeout, proceeding with anonymous");
69
+ }
70
+ resolve(undefined);
71
+ }, timeoutMs);
72
+ });
73
+ };
74
+
25
75
  export const initializeSubscription = async (
26
76
  config: SubscriptionInitConfig,
27
77
  ): Promise<void> => {
@@ -36,6 +86,7 @@ export const initializeSubscription = async (
36
86
  onCreditsUpdated,
37
87
  onCreditRenewal,
38
88
  timeoutMs = 10000,
89
+ authStateTimeoutMs = 2000,
39
90
  } = config;
40
91
 
41
92
  if (!apiKey) {
@@ -56,7 +107,16 @@ export const initializeSubscription = async (
56
107
  getAnonymousUserId,
57
108
  });
58
109
 
59
- const initPromise = SubscriptionManager.initialize();
110
+ // Wait for auth state to get correct user ID
111
+ const initialUserId = await waitForAuthState(getFirebaseAuth, authStateTimeoutMs);
112
+
113
+ if (__DEV__) {
114
+ console.log("[Subscription] Initializing with user:", {
115
+ userId: initialUserId ?? "will use anonymous",
116
+ });
117
+ }
118
+
119
+ const initPromise = SubscriptionManager.initialize(initialUserId);
60
120
  const timeoutPromise = new Promise<boolean>((_, reject) =>
61
121
  setTimeout(
62
122
  () => reject(new Error("Subscription initialization timeout")),
@@ -76,7 +136,6 @@ export const initializeSubscription = async (
76
136
  });
77
137
 
78
138
  if (__DEV__) {
79
-
80
139
  console.log("[Subscription] Initialized successfully");
81
140
  }
82
141
  };
@@ -117,7 +117,31 @@ export async function initializeSDK(
117
117
  // Case 2: Already configured but different user or re-initializing
118
118
  if (isPurchasesConfigured) {
119
119
  try {
120
- const { customerInfo } = await Purchases.logIn(userId);
120
+ // Check if we're already logged in with this user ID
121
+ const currentAppUserId = await Purchases.getAppUserID();
122
+
123
+ if (__DEV__) {
124
+ console.log('[DEBUG RevenueCatInitializer] Current app user ID check', {
125
+ currentAppUserId,
126
+ requestedUserId: userId,
127
+ needsLogin: currentAppUserId !== userId,
128
+ });
129
+ }
130
+
131
+ // Only call logIn if the user ID is different
132
+ let customerInfo;
133
+ if (currentAppUserId !== userId) {
134
+ if (__DEV__) {
135
+ console.log('[DEBUG RevenueCatInitializer] User ID changed, calling logIn');
136
+ }
137
+ const result = await Purchases.logIn(userId);
138
+ customerInfo = result.customerInfo;
139
+ } else {
140
+ if (__DEV__) {
141
+ console.log('[DEBUG RevenueCatInitializer] Already logged in with same user ID, skipping logIn');
142
+ }
143
+ customerInfo = await Purchases.getCustomerInfo();
144
+ }
121
145
 
122
146
  deps.setInitialized(true);
123
147
  deps.setCurrentUserId(userId);