chub-dev 0.1.0 → 0.1.2-beta.0

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.
Files changed (139) hide show
  1. package/README.md +55 -0
  2. package/bin/chub-mcp +2 -0
  3. package/dist/airtable/docs/database/javascript/DOC.md +1437 -0
  4. package/dist/airtable/docs/database/python/DOC.md +1735 -0
  5. package/dist/amplitude/docs/analytics/javascript/DOC.md +1282 -0
  6. package/dist/amplitude/docs/analytics/python/DOC.md +1199 -0
  7. package/dist/anthropic/docs/claude-api/javascript/DOC.md +503 -0
  8. package/dist/anthropic/docs/claude-api/python/DOC.md +389 -0
  9. package/dist/asana/docs/tasks/DOC.md +1396 -0
  10. package/dist/assemblyai/docs/transcription/DOC.md +1043 -0
  11. package/dist/atlassian/docs/confluence/javascript/DOC.md +1347 -0
  12. package/dist/atlassian/docs/confluence/python/DOC.md +1604 -0
  13. package/dist/auth0/docs/identity/javascript/DOC.md +968 -0
  14. package/dist/auth0/docs/identity/python/DOC.md +1199 -0
  15. package/dist/aws/docs/s3/javascript/DOC.md +1773 -0
  16. package/dist/aws/docs/s3/python/DOC.md +1807 -0
  17. package/dist/binance/docs/trading/javascript/DOC.md +1315 -0
  18. package/dist/binance/docs/trading/python/DOC.md +1454 -0
  19. package/dist/braintree/docs/gateway/javascript/DOC.md +1278 -0
  20. package/dist/braintree/docs/gateway/python/DOC.md +1179 -0
  21. package/dist/chromadb/docs/embeddings-db/javascript/DOC.md +1263 -0
  22. package/dist/chromadb/docs/embeddings-db/python/DOC.md +1707 -0
  23. package/dist/clerk/docs/auth/javascript/DOC.md +1220 -0
  24. package/dist/clerk/docs/auth/python/DOC.md +274 -0
  25. package/dist/cloudflare/docs/workers/javascript/DOC.md +918 -0
  26. package/dist/cloudflare/docs/workers/python/DOC.md +994 -0
  27. package/dist/cockroachdb/docs/distributed-db/DOC.md +1500 -0
  28. package/dist/cohere/docs/llm/DOC.md +1335 -0
  29. package/dist/datadog/docs/monitoring/javascript/DOC.md +1740 -0
  30. package/dist/datadog/docs/monitoring/python/DOC.md +1815 -0
  31. package/dist/deepgram/docs/speech/javascript/DOC.md +885 -0
  32. package/dist/deepgram/docs/speech/python/DOC.md +685 -0
  33. package/dist/deepl/docs/translation/javascript/DOC.md +887 -0
  34. package/dist/deepl/docs/translation/python/DOC.md +944 -0
  35. package/dist/deepseek/docs/llm/DOC.md +1220 -0
  36. package/dist/directus/docs/headless-cms/javascript/DOC.md +1128 -0
  37. package/dist/directus/docs/headless-cms/python/DOC.md +1276 -0
  38. package/dist/discord/docs/bot/javascript/DOC.md +1090 -0
  39. package/dist/discord/docs/bot/python/DOC.md +1130 -0
  40. package/dist/elasticsearch/docs/search/DOC.md +1634 -0
  41. package/dist/elevenlabs/docs/text-to-speech/javascript/DOC.md +336 -0
  42. package/dist/elevenlabs/docs/text-to-speech/python/DOC.md +552 -0
  43. package/dist/firebase/docs/auth/DOC.md +1015 -0
  44. package/dist/gemini/docs/genai/javascript/DOC.md +691 -0
  45. package/dist/gemini/docs/genai/python/DOC.md +555 -0
  46. package/dist/github/docs/octokit/DOC.md +1560 -0
  47. package/dist/google/docs/bigquery/javascript/DOC.md +1688 -0
  48. package/dist/google/docs/bigquery/python/DOC.md +1503 -0
  49. package/dist/hubspot/docs/crm/javascript/DOC.md +1805 -0
  50. package/dist/hubspot/docs/crm/python/DOC.md +2033 -0
  51. package/dist/huggingface/docs/transformers/DOC.md +948 -0
  52. package/dist/intercom/docs/messaging/javascript/DOC.md +1844 -0
  53. package/dist/intercom/docs/messaging/python/DOC.md +1797 -0
  54. package/dist/jira/docs/issues/javascript/DOC.md +1420 -0
  55. package/dist/jira/docs/issues/python/DOC.md +1492 -0
  56. package/dist/kafka/docs/streaming/javascript/DOC.md +1671 -0
  57. package/dist/kafka/docs/streaming/python/DOC.md +1464 -0
  58. package/dist/landingai-ade/docs/api/DOC.md +620 -0
  59. package/dist/landingai-ade/docs/sdk/python/DOC.md +489 -0
  60. package/dist/landingai-ade/docs/sdk/typescript/DOC.md +542 -0
  61. package/dist/landingai-ade/skills/SKILL.md +489 -0
  62. package/dist/launchdarkly/docs/feature-flags/javascript/DOC.md +1191 -0
  63. package/dist/launchdarkly/docs/feature-flags/python/DOC.md +1671 -0
  64. package/dist/linear/docs/tracker/DOC.md +1554 -0
  65. package/dist/livekit/docs/realtime/javascript/DOC.md +303 -0
  66. package/dist/livekit/docs/realtime/python/DOC.md +163 -0
  67. package/dist/mailchimp/docs/marketing/DOC.md +1420 -0
  68. package/dist/meilisearch/docs/search/DOC.md +1241 -0
  69. package/dist/microsoft/docs/onedrive/javascript/DOC.md +1421 -0
  70. package/dist/microsoft/docs/onedrive/python/DOC.md +1549 -0
  71. package/dist/mongodb/docs/atlas/DOC.md +2041 -0
  72. package/dist/notion/docs/workspace-api/javascript/DOC.md +1435 -0
  73. package/dist/notion/docs/workspace-api/python/DOC.md +1400 -0
  74. package/dist/okta/docs/identity/javascript/DOC.md +1171 -0
  75. package/dist/okta/docs/identity/python/DOC.md +1401 -0
  76. package/dist/openai/docs/chat/javascript/DOC.md +407 -0
  77. package/dist/openai/docs/chat/python/DOC.md +568 -0
  78. package/dist/paypal/docs/checkout/DOC.md +278 -0
  79. package/dist/pinecone/docs/sdk/javascript/DOC.md +984 -0
  80. package/dist/pinecone/docs/sdk/python/DOC.md +1395 -0
  81. package/dist/plaid/docs/banking/javascript/DOC.md +1163 -0
  82. package/dist/plaid/docs/banking/python/DOC.md +1203 -0
  83. package/dist/playwright-community/skills/login-flows/SKILL.md +108 -0
  84. package/dist/postmark/docs/transactional-email/DOC.md +1168 -0
  85. package/dist/prisma/docs/orm/javascript/DOC.md +1419 -0
  86. package/dist/prisma/docs/orm/python/DOC.md +1317 -0
  87. package/dist/qdrant/docs/vector-search/javascript/DOC.md +1221 -0
  88. package/dist/qdrant/docs/vector-search/python/DOC.md +1653 -0
  89. package/dist/rabbitmq/docs/message-queue/javascript/DOC.md +1193 -0
  90. package/dist/rabbitmq/docs/message-queue/python/DOC.md +1243 -0
  91. package/dist/razorpay/docs/payments/javascript/DOC.md +1219 -0
  92. package/dist/razorpay/docs/payments/python/DOC.md +1330 -0
  93. package/dist/redis/docs/key-value/javascript/DOC.md +1851 -0
  94. package/dist/redis/docs/key-value/python/DOC.md +2054 -0
  95. package/dist/registry.json +2817 -0
  96. package/dist/replicate/docs/model-hosting/DOC.md +1318 -0
  97. package/dist/resend/docs/email/DOC.md +1271 -0
  98. package/dist/salesforce/docs/crm/javascript/DOC.md +1241 -0
  99. package/dist/salesforce/docs/crm/python/DOC.md +1183 -0
  100. package/dist/search-index.json +1 -0
  101. package/dist/sendgrid/docs/email-api/javascript/DOC.md +371 -0
  102. package/dist/sendgrid/docs/email-api/python/DOC.md +656 -0
  103. package/dist/sentry/docs/error-tracking/javascript/DOC.md +1073 -0
  104. package/dist/sentry/docs/error-tracking/python/DOC.md +1309 -0
  105. package/dist/shopify/docs/storefront/DOC.md +457 -0
  106. package/dist/slack/docs/workspace/javascript/DOC.md +933 -0
  107. package/dist/slack/docs/workspace/python/DOC.md +271 -0
  108. package/dist/square/docs/payments/javascript/DOC.md +1855 -0
  109. package/dist/square/docs/payments/python/DOC.md +1728 -0
  110. package/dist/stripe/docs/api/DOC.md +1727 -0
  111. package/dist/stripe/docs/payments/DOC.md +1726 -0
  112. package/dist/stytch/docs/auth/javascript/DOC.md +1813 -0
  113. package/dist/stytch/docs/auth/python/DOC.md +1962 -0
  114. package/dist/supabase/docs/client/DOC.md +1606 -0
  115. package/dist/twilio/docs/messaging/python/DOC.md +469 -0
  116. package/dist/twilio/docs/messaging/typescript/DOC.md +946 -0
  117. package/dist/vercel/docs/platform/DOC.md +1940 -0
  118. package/dist/weaviate/docs/vector-db/javascript/DOC.md +1268 -0
  119. package/dist/weaviate/docs/vector-db/python/DOC.md +1388 -0
  120. package/dist/zendesk/docs/support/javascript/DOC.md +2150 -0
  121. package/dist/zendesk/docs/support/python/DOC.md +2297 -0
  122. package/package.json +22 -6
  123. package/skills/get-api-docs/SKILL.md +84 -0
  124. package/src/commands/annotate.js +83 -0
  125. package/src/commands/build.js +12 -1
  126. package/src/commands/feedback.js +150 -0
  127. package/src/commands/get.js +83 -42
  128. package/src/commands/search.js +7 -0
  129. package/src/index.js +43 -17
  130. package/src/lib/analytics.js +90 -0
  131. package/src/lib/annotations.js +57 -0
  132. package/src/lib/bm25.js +170 -0
  133. package/src/lib/cache.js +69 -6
  134. package/src/lib/config.js +8 -3
  135. package/src/lib/identity.js +99 -0
  136. package/src/lib/registry.js +103 -20
  137. package/src/lib/telemetry.js +86 -0
  138. package/src/mcp/server.js +177 -0
  139. package/src/mcp/tools.js +251 -0
@@ -0,0 +1,1015 @@
1
+ ---
2
+ name: auth
3
+ description: "Firebase Authentication JavaScript SDK - Comprehensive coding guide for Firebase auth in JavaScript projects"
4
+ metadata:
5
+ languages: "javascript"
6
+ versions: "12.4.0"
7
+ updated-on: "2026-03-02"
8
+ source: maintainer
9
+ tags: "firebase,auth,google,identity,session"
10
+ ---
11
+
12
+ # Firebase Authentication JavaScript SDK - Comprehensive Coding Guide
13
+
14
+ ## 1. Golden Rule
15
+
16
+ **Always use the official Firebase Authentication package:**
17
+ - Package: `firebase/auth` (modular SDK)
18
+ - Legacy: `@firebase/auth` (use only if maintaining legacy code)
19
+
20
+ **Never use deprecated Firebase namespaced imports.** The modular SDK is the only recommended approach for new projects.
21
+
22
+ ## 2. Installation
23
+
24
+ ### npm
25
+ ```bash
26
+ npm install firebase
27
+ ```
28
+
29
+ ### yarn
30
+ ```bash
31
+ yarn add firebase
32
+ ```
33
+
34
+ ### pnpm
35
+ ```bash
36
+ pnpm add firebase
37
+ ```
38
+
39
+ **Environment Variables (Optional):**
40
+ ```bash
41
+ FIREBASE_API_KEY=your_api_key_here
42
+ FIREBASE_AUTH_DOMAIN=your-project.firebaseapp.com
43
+ FIREBASE_PROJECT_ID=your-project-id
44
+ ```
45
+
46
+ ## 3. Initialization
47
+
48
+ ### Basic Initialization
49
+ ```javascript
50
+ import { initializeApp } from 'firebase/app';
51
+ import { getAuth } from 'firebase/auth';
52
+
53
+ const firebaseConfig = {
54
+ apiKey: "your-api-key",
55
+ authDomain: "your-project.firebaseapp.com",
56
+ projectId: "your-project-id"
57
+ };
58
+
59
+ const app = initializeApp(firebaseConfig);
60
+ const auth = getAuth(app);
61
+ ```
62
+
63
+ ### Advanced Initialization
64
+
65
+ #### Custom Settings with Dependencies
66
+ ```javascript
67
+ import {
68
+ initializeAuth,
69
+ browserLocalPersistence,
70
+ browserPopupRedirectResolver
71
+ } from 'firebase/auth';
72
+
73
+ const auth = initializeAuth(app, {
74
+ persistence: browserLocalPersistence,
75
+ popupRedirectResolver: browserPopupRedirectResolver
76
+ });
77
+ ```
78
+
79
+ #### Cordova/Capacitor Initialization
80
+ ```javascript
81
+ import {
82
+ initializeAuth,
83
+ indexedDBLocalPersistence,
84
+ cordovaPopupRedirectResolver
85
+ } from 'firebase/auth';
86
+
87
+ const auth = initializeAuth(app, {
88
+ persistence: indexedDBLocalPersistence,
89
+ popupRedirectResolver: cordovaPopupRedirectResolver
90
+ });
91
+ ```
92
+
93
+ ### Emulator Connection
94
+ ```javascript
95
+ import { connectAuthEmulator } from 'firebase/auth';
96
+
97
+ // Connect to local emulator (must be called before any operations)
98
+ connectAuthEmulator(auth, 'http://localhost:9099');
99
+ ```
100
+
101
+ ## 4. Core API Surfaces
102
+
103
+ ### Email/Password Authentication
104
+
105
+ #### Minimal Example - Sign Up
106
+ ```javascript
107
+ import { createUserWithEmailAndPassword } from 'firebase/auth';
108
+
109
+ const userCredential = await createUserWithEmailAndPassword(
110
+ auth,
111
+ 'user@example.com',
112
+ 'password123'
113
+ );
114
+ ```
115
+
116
+ #### Minimal Example - Sign In
117
+ ```javascript
118
+ import { signInWithEmailAndPassword } from 'firebase/auth';
119
+
120
+ const userCredential = await signInWithEmailAndPassword(
121
+ auth,
122
+ 'user@example.com',
123
+ 'password123'
124
+ );
125
+ ```
126
+
127
+ #### Minimal Example - Sign Out
128
+ ```javascript
129
+ import { signOut } from 'firebase/auth';
130
+
131
+ await signOut(auth);
132
+ ```
133
+
134
+ #### Advanced Example - Password Reset
135
+ ```javascript
136
+ import { sendPasswordResetEmail } from 'firebase/auth';
137
+
138
+ await sendPasswordResetEmail(auth, 'user@example.com', {
139
+ url: 'https://myapp.com/login',
140
+ handleCodeInApp: false
141
+ });
142
+ ```
143
+
144
+ #### Advanced Example - Update Password
145
+ ```javascript
146
+ import { updatePassword } from 'firebase/auth';
147
+
148
+ const user = auth.currentUser;
149
+ await updatePassword(user, 'newPassword123');
150
+ ```
151
+
152
+ #### Email Verification
153
+ ```javascript
154
+ import { sendEmailVerification } from 'firebase/auth';
155
+
156
+ const user = auth.currentUser;
157
+ await sendEmailVerification(user, {
158
+ url: 'https://myapp.com/verify',
159
+ handleCodeInApp: true
160
+ });
161
+ ```
162
+
163
+ ### Social Authentication (OAuth Providers)
164
+
165
+ #### Minimal Example - Google Sign In (Popup)
166
+ ```javascript
167
+ import { signInWithPopup, GoogleAuthProvider } from 'firebase/auth';
168
+
169
+ const provider = new GoogleAuthProvider();
170
+ const result = await signInWithPopup(auth, provider);
171
+ ```
172
+
173
+ #### Advanced Example - Google Sign In with Scopes
174
+ ```javascript
175
+ import { signInWithPopup, GoogleAuthProvider } from 'firebase/auth';
176
+
177
+ const provider = new GoogleAuthProvider();
178
+ provider.addScope('https://www.googleapis.com/auth/contacts.readonly');
179
+ provider.setCustomParameters({
180
+ prompt: 'select_account'
181
+ });
182
+
183
+ const result = await signInWithPopup(auth, provider);
184
+ const credential = GoogleAuthProvider.credentialFromResult(result);
185
+ const accessToken = credential.accessToken;
186
+ ```
187
+
188
+ #### Redirect Flow (Mobile/Better UX)
189
+ ```javascript
190
+ import { signInWithRedirect, getRedirectResult, GoogleAuthProvider } from 'firebase/auth';
191
+
192
+ // Initiate redirect
193
+ const provider = new GoogleAuthProvider();
194
+ await signInWithRedirect(auth, provider);
195
+
196
+ // After redirect, get result
197
+ const result = await getRedirectResult(auth);
198
+ if (result) {
199
+ const user = result.user;
200
+ }
201
+ ```
202
+
203
+ #### Facebook Authentication
204
+ ```javascript
205
+ import { signInWithPopup, FacebookAuthProvider } from 'firebase/auth';
206
+
207
+ const provider = new FacebookAuthProvider();
208
+ provider.addScope('user_birthday');
209
+ const result = await signInWithPopup(auth, provider);
210
+ ```
211
+
212
+ #### GitHub Authentication
213
+ ```javascript
214
+ import { signInWithPopup, GithubAuthProvider } from 'firebase/auth';
215
+
216
+ const provider = new GithubAuthProvider();
217
+ provider.addScope('repo');
218
+ const result = await signInWithPopup(auth, provider);
219
+ ```
220
+
221
+ #### Twitter/X Authentication
222
+ ```javascript
223
+ import { signInWithPopup, TwitterAuthProvider } from 'firebase/auth';
224
+
225
+ const provider = new TwitterAuthProvider();
226
+ const result = await signInWithPopup(auth, provider);
227
+ ```
228
+
229
+ #### Microsoft Authentication
230
+ ```javascript
231
+ import { signInWithPopup, OAuthProvider } from 'firebase/auth';
232
+
233
+ const provider = new OAuthProvider('microsoft.com');
234
+ provider.addScope('mail.read');
235
+ const result = await signInWithPopup(auth, provider);
236
+ ```
237
+
238
+ #### Apple Authentication
239
+ ```javascript
240
+ import { signInWithPopup, OAuthProvider } from 'firebase/auth';
241
+
242
+ const provider = new OAuthProvider('apple.com');
243
+ provider.addScope('email');
244
+ provider.addScope('name');
245
+ const result = await signInWithPopup(auth, provider);
246
+ ```
247
+
248
+ ### Phone Authentication
249
+
250
+ #### Minimal Example - Send Verification Code
251
+ ```javascript
252
+ import { RecaptchaVerifier, signInWithPhoneNumber } from 'firebase/auth';
253
+
254
+ // Setup reCAPTCHA
255
+ const recaptchaVerifier = new RecaptchaVerifier(auth, 'recaptcha-container', {
256
+ size: 'invisible'
257
+ });
258
+
259
+ // Send code
260
+ const confirmationResult = await signInWithPhoneNumber(
261
+ auth,
262
+ '+1234567890',
263
+ recaptchaVerifier
264
+ );
265
+ ```
266
+
267
+ #### Advanced Example - Verify Code
268
+ ```javascript
269
+ // User enters verification code
270
+ const code = '123456';
271
+ const result = await confirmationResult.confirm(code);
272
+ const user = result.user;
273
+ ```
274
+
275
+ #### Visible reCAPTCHA
276
+ ```javascript
277
+ const recaptchaVerifier = new RecaptchaVerifier(auth, 'recaptcha-container', {
278
+ size: 'normal',
279
+ callback: (response) => {
280
+ // reCAPTCHA solved
281
+ },
282
+ 'expired-callback': () => {
283
+ // reCAPTCHA expired
284
+ }
285
+ });
286
+
287
+ recaptchaVerifier.render();
288
+ ```
289
+
290
+ ### Anonymous Authentication
291
+
292
+ #### Minimal Example
293
+ ```javascript
294
+ import { signInAnonymously } from 'firebase/auth';
295
+
296
+ const userCredential = await signInAnonymously(auth);
297
+ const user = userCredential.user;
298
+ console.log('Anonymous user ID:', user.uid);
299
+ ```
300
+
301
+ #### Link Anonymous Account to Email
302
+ ```javascript
303
+ import { linkWithCredential, EmailAuthProvider } from 'firebase/auth';
304
+
305
+ const credential = EmailAuthProvider.credential('user@example.com', 'password123');
306
+ const userCredential = await linkWithCredential(auth.currentUser, credential);
307
+ ```
308
+
309
+ ### Custom Token Authentication
310
+
311
+ #### Minimal Example
312
+ ```javascript
313
+ import { signInWithCustomToken } from 'firebase/auth';
314
+
315
+ // Token generated on your server
316
+ const customToken = 'your-custom-token';
317
+ const userCredential = await signInWithCustomToken(auth, customToken);
318
+ ```
319
+
320
+ ### Email Link Authentication
321
+
322
+ #### Send Sign-In Link
323
+ ```javascript
324
+ import { sendSignInLinkToEmail } from 'firebase/auth';
325
+
326
+ const actionCodeSettings = {
327
+ url: 'https://www.example.com/finishSignUp?cartId=1234',
328
+ handleCodeInApp: true,
329
+ iOS: {
330
+ bundleId: 'com.example.ios'
331
+ },
332
+ android: {
333
+ packageName: 'com.example.android',
334
+ installApp: true,
335
+ minimumVersion: '12'
336
+ }
337
+ };
338
+
339
+ await sendSignInLinkToEmail(auth, 'user@example.com', actionCodeSettings);
340
+ // Save email to verify after redirect
341
+ window.localStorage.setItem('emailForSignIn', 'user@example.com');
342
+ ```
343
+
344
+ #### Complete Sign-In with Email Link
345
+ ```javascript
346
+ import { isSignInWithEmailLink, signInWithEmailLink } from 'firebase/auth';
347
+
348
+ // Confirm the link is a sign-in with email link
349
+ if (isSignInWithEmailLink(auth, window.location.href)) {
350
+ let email = window.localStorage.getItem('emailForSignIn');
351
+ if (!email) {
352
+ email = window.prompt('Please provide your email for confirmation');
353
+ }
354
+
355
+ const result = await signInWithEmailLink(auth, email, window.location.href);
356
+ window.localStorage.removeItem('emailForSignIn');
357
+ }
358
+ ```
359
+
360
+ ### SAML Authentication
361
+
362
+ #### Sign In with SAML
363
+ ```javascript
364
+ import { signInWithPopup, SAMLAuthProvider } from 'firebase/auth';
365
+
366
+ const provider = new SAMLAuthProvider('saml.provider-id');
367
+ const result = await signInWithPopup(auth, provider);
368
+ ```
369
+
370
+ ### Multi-Factor Authentication (MFA)
371
+
372
+ #### Enroll User in Phone MFA
373
+ ```javascript
374
+ import { multiFactor, PhoneAuthProvider, PhoneMultiFactorGenerator } from 'firebase/auth';
375
+
376
+ const user = auth.currentUser;
377
+ const multiFactorSession = await multiFactor(user).getSession();
378
+
379
+ const phoneAuthProvider = new PhoneAuthProvider(auth);
380
+ const verificationId = await phoneAuthProvider.verifyPhoneNumber(
381
+ '+1234567890',
382
+ recaptchaVerifier,
383
+ multiFactorSession
384
+ );
385
+
386
+ const verificationCode = '123456'; // User enters code
387
+ const phoneAuthCredential = PhoneAuthProvider.credential(verificationId, verificationCode);
388
+ const multiFactorAssertion = PhoneMultiFactorGenerator.assertion(phoneAuthCredential);
389
+
390
+ await multiFactor(user).enroll(multiFactorAssertion, 'Personal phone');
391
+ ```
392
+
393
+ #### Enroll User in TOTP MFA
394
+ ```javascript
395
+ import { multiFactor, TotpMultiFactorGenerator, TotpSecret } from 'firebase/auth';
396
+
397
+ const user = auth.currentUser;
398
+ const multiFactorSession = await multiFactor(user).getSession();
399
+
400
+ // Generate TOTP secret
401
+ const totpSecret = await TotpSecret.generate(auth, multiFactorSession);
402
+
403
+ // Display QR code to user
404
+ const qrCodeUrl = totpSecret.generateQrCodeUrl(user.email, 'MyApp');
405
+ console.log('QR Code URL:', qrCodeUrl);
406
+
407
+ // User scans QR code and enters verification code
408
+ const verificationCode = '123456';
409
+ const multiFactorAssertion = TotpMultiFactorGenerator.assertionForEnrollment(
410
+ totpSecret,
411
+ verificationCode
412
+ );
413
+
414
+ await multiFactor(user).enroll(multiFactorAssertion, 'TOTP device');
415
+ ```
416
+
417
+ #### Sign In with Phone MFA
418
+ ```javascript
419
+ import { getMultiFactorResolver, PhoneAuthProvider, PhoneMultiFactorGenerator } from 'firebase/auth';
420
+
421
+ try {
422
+ await signInWithEmailAndPassword(auth, email, password);
423
+ } catch (error) {
424
+ if (error.code === 'auth/multi-factor-auth-required') {
425
+ const resolver = getMultiFactorResolver(auth, error);
426
+
427
+ const phoneAuthProvider = new PhoneAuthProvider(auth);
428
+ const verificationId = await phoneAuthProvider.verifyPhoneNumber(
429
+ resolver.hints[0].phoneNumber,
430
+ recaptchaVerifier
431
+ );
432
+
433
+ const verificationCode = '123456'; // User enters code
434
+ const phoneAuthCredential = PhoneAuthProvider.credential(verificationId, verificationCode);
435
+ const multiFactorAssertion = PhoneMultiFactorGenerator.assertion(phoneAuthCredential);
436
+
437
+ const userCredential = await resolver.resolveSignIn(multiFactorAssertion);
438
+ }
439
+ }
440
+ ```
441
+
442
+ #### Sign In with TOTP MFA
443
+ ```javascript
444
+ import { getMultiFactorResolver, TotpMultiFactorGenerator } from 'firebase/auth';
445
+
446
+ try {
447
+ await signInWithEmailAndPassword(auth, email, password);
448
+ } catch (error) {
449
+ if (error.code === 'auth/multi-factor-auth-required') {
450
+ const resolver = getMultiFactorResolver(auth, error);
451
+
452
+ // Select TOTP factor
453
+ const totpInfo = resolver.hints.find(hint => hint.factorId === 'totp');
454
+
455
+ const verificationCode = '123456'; // User enters TOTP code
456
+ const multiFactorAssertion = TotpMultiFactorGenerator.assertionForSignIn(
457
+ totpInfo.uid,
458
+ verificationCode
459
+ );
460
+
461
+ const userCredential = await resolver.resolveSignIn(multiFactorAssertion);
462
+ }
463
+ }
464
+ ```
465
+
466
+ #### Unenroll from MFA
467
+ ```javascript
468
+ import { multiFactor } from 'firebase/auth';
469
+
470
+ const user = auth.currentUser;
471
+ const enrolledFactors = multiFactor(user).enrolledFactors;
472
+
473
+ // Unenroll from specific factor
474
+ await multiFactor(user).unenroll(enrolledFactors[0]);
475
+ ```
476
+
477
+ ## 5. Advanced Features
478
+
479
+ ### User State Management
480
+
481
+ #### Auth State Observer
482
+ ```javascript
483
+ import { onAuthStateChanged } from 'firebase/auth';
484
+
485
+ const unsubscribe = onAuthStateChanged(auth, (user) => {
486
+ if (user) {
487
+ console.log('User is signed in:', user.uid);
488
+ } else {
489
+ console.log('User is signed out');
490
+ }
491
+ });
492
+
493
+ // Cleanup
494
+ unsubscribe();
495
+ ```
496
+
497
+ #### ID Token Changed Listener
498
+ ```javascript
499
+ import { onIdTokenChanged } from 'firebase/auth';
500
+
501
+ const unsubscribe = onIdTokenChanged(auth, (user) => {
502
+ if (user) {
503
+ // Get fresh token
504
+ user.getIdToken().then((token) => {
505
+ console.log('Fresh token:', token);
506
+ });
507
+ }
508
+ });
509
+ ```
510
+
511
+ #### Before Auth State Changed (Blocking Callback)
512
+ ```javascript
513
+ import { beforeAuthStateChanged } from 'firebase/auth';
514
+
515
+ const unsubscribe = beforeAuthStateChanged(
516
+ auth,
517
+ async (user) => {
518
+ // Runs before auth state changes
519
+ // Can be async and block the state change
520
+ if (user) {
521
+ console.log('User about to be set:', user.uid);
522
+ // Perform any necessary checks
523
+ }
524
+ },
525
+ () => {
526
+ // onAbort callback - called if a later beforeAuthStateChanged throws
527
+ console.log('Auth state change was aborted');
528
+ }
529
+ );
530
+ ```
531
+
532
+ #### Update Current User
533
+ ```javascript
534
+ import { updateCurrentUser } from 'firebase/auth';
535
+
536
+ // Set a different user as current user
537
+ await updateCurrentUser(auth, newUser);
538
+ ```
539
+
540
+ #### Get Current User
541
+ ```javascript
542
+ const user = auth.currentUser;
543
+
544
+ if (user) {
545
+ console.log('User ID:', user.uid);
546
+ console.log('Email:', user.email);
547
+ console.log('Display Name:', user.displayName);
548
+ console.log('Photo URL:', user.photoURL);
549
+ console.log('Email Verified:', user.emailVerified);
550
+ }
551
+ ```
552
+
553
+ ### User Profile Management
554
+
555
+ #### Update Profile
556
+ ```javascript
557
+ import { updateProfile } from 'firebase/auth';
558
+
559
+ const user = auth.currentUser;
560
+ await updateProfile(user, {
561
+ displayName: 'John Doe',
562
+ photoURL: 'https://example.com/photo.jpg'
563
+ });
564
+ ```
565
+
566
+ #### Update Email (Deprecated)
567
+ ```javascript
568
+ import { updateEmail, sendEmailVerification } from 'firebase/auth';
569
+
570
+ const user = auth.currentUser;
571
+ await updateEmail(user, 'newemail@example.com');
572
+ await sendEmailVerification(user);
573
+ ```
574
+
575
+ #### Update Email with Verification (Recommended)
576
+ ```javascript
577
+ import { verifyBeforeUpdateEmail } from 'firebase/auth';
578
+
579
+ const actionCodeSettings = {
580
+ url: 'https://www.example.com/?email=user@example.com'
581
+ };
582
+
583
+ const user = auth.currentUser;
584
+ await verifyBeforeUpdateEmail(user, 'newemail@example.com', actionCodeSettings);
585
+ // User must verify new email before it takes effect
586
+ ```
587
+
588
+ #### Update Phone Number
589
+ ```javascript
590
+ import { updatePhoneNumber, PhoneAuthProvider } from 'firebase/auth';
591
+
592
+ // First get phone credential
593
+ const phoneAuthProvider = new PhoneAuthProvider(auth);
594
+ const verificationId = await phoneAuthProvider.verifyPhoneNumber(
595
+ '+1234567890',
596
+ recaptchaVerifier
597
+ );
598
+
599
+ const verificationCode = '123456'; // User enters code
600
+ const phoneCredential = PhoneAuthProvider.credential(verificationId, verificationCode);
601
+
602
+ const user = auth.currentUser;
603
+ await updatePhoneNumber(user, phoneCredential);
604
+ ```
605
+
606
+ #### Reload User Data
607
+ ```javascript
608
+ import { reload } from 'firebase/auth';
609
+
610
+ await reload(auth.currentUser);
611
+ const updatedUser = auth.currentUser;
612
+ ```
613
+
614
+ #### Delete User Account
615
+ ```javascript
616
+ import { deleteUser } from 'firebase/auth';
617
+
618
+ const user = auth.currentUser;
619
+ await deleteUser(user);
620
+ ```
621
+
622
+ ### Token Management
623
+
624
+ #### Get ID Token
625
+ ```javascript
626
+ const user = auth.currentUser;
627
+ const token = await user.getIdToken();
628
+ const refreshedToken = await user.getIdToken(true); // Force refresh
629
+ ```
630
+
631
+ #### Get ID Token Result (with Claims)
632
+ ```javascript
633
+ import { getIdToken, getIdTokenResult } from 'firebase/auth';
634
+
635
+ const user = auth.currentUser;
636
+
637
+ // Using user method
638
+ const token = await getIdToken(user);
639
+ const idTokenResult = await getIdTokenResult(user);
640
+
641
+ console.log('Token:', idTokenResult.token);
642
+ console.log('Expiration:', idTokenResult.expirationTime);
643
+ console.log('Custom Claims:', idTokenResult.claims);
644
+ console.log('Auth Time:', idTokenResult.authTime);
645
+ console.log('Issued At:', idTokenResult.issuedAtTime);
646
+ console.log('Sign-in Provider:', idTokenResult.signInProvider);
647
+ ```
648
+
649
+ ### Password Validation
650
+
651
+ #### Validate Password Against Policy
652
+ ```javascript
653
+ import { validatePassword } from 'firebase/auth';
654
+
655
+ const validationStatus = await validatePassword(auth, 'MyPassword123!');
656
+
657
+ console.log('Is valid:', validationStatus.isValid);
658
+ console.log('Contains lowercase:', validationStatus.containsLowercaseLetter);
659
+ console.log('Contains uppercase:', validationStatus.containsUppercaseLetter);
660
+ console.log('Contains numeric:', validationStatus.containsNumericCharacter);
661
+ console.log('Contains non-alphanumeric:', validationStatus.containsNonAlphanumericCharacter);
662
+ console.log('Meets min length:', validationStatus.meetsMinPasswordLength);
663
+ console.log('Meets max length:', validationStatus.meetsMaxPasswordLength);
664
+ ```
665
+
666
+ ### Account Linking
667
+
668
+ #### Link Multiple Providers
669
+ ```javascript
670
+ import { linkWithPopup, GoogleAuthProvider } from 'firebase/auth';
671
+
672
+ const provider = new GoogleAuthProvider();
673
+ const result = await linkWithPopup(auth.currentUser, provider);
674
+ ```
675
+
676
+ #### Link with Credential
677
+ ```javascript
678
+ import { linkWithCredential, EmailAuthProvider } from 'firebase/auth';
679
+
680
+ const credential = EmailAuthProvider.credential('user@example.com', 'password123');
681
+ await linkWithCredential(auth.currentUser, credential);
682
+ ```
683
+
684
+ #### Link with Phone Number
685
+ ```javascript
686
+ import { linkWithPhoneNumber } from 'firebase/auth';
687
+
688
+ const confirmationResult = await linkWithPhoneNumber(
689
+ auth.currentUser,
690
+ '+1234567890',
691
+ recaptchaVerifier
692
+ );
693
+
694
+ const verificationCode = '123456';
695
+ await confirmationResult.confirm(verificationCode);
696
+ ```
697
+
698
+ #### Link with Redirect
699
+ ```javascript
700
+ import { linkWithRedirect, GoogleAuthProvider } from 'firebase/auth';
701
+
702
+ const provider = new GoogleAuthProvider();
703
+ await linkWithRedirect(auth.currentUser, provider);
704
+
705
+ // After redirect, check result
706
+ const result = await getRedirectResult(auth);
707
+ ```
708
+
709
+ #### Unlink Provider
710
+ ```javascript
711
+ import { unlink } from 'firebase/auth';
712
+
713
+ await unlink(auth.currentUser, 'google.com');
714
+ ```
715
+
716
+ #### Fetch Sign-In Methods
717
+ ```javascript
718
+ import { fetchSignInMethodsForEmail } from 'firebase/auth';
719
+
720
+ const methods = await fetchSignInMethodsForEmail(auth, 'user@example.com');
721
+ console.log('Available sign-in methods:', methods);
722
+ ```
723
+
724
+ ### Re-authentication
725
+
726
+ #### Re-authenticate User
727
+ ```javascript
728
+ import { reauthenticateWithCredential, EmailAuthProvider } from 'firebase/auth';
729
+
730
+ const user = auth.currentUser;
731
+ const credential = EmailAuthProvider.credential(user.email, 'current-password');
732
+
733
+ await reauthenticateWithCredential(user, credential);
734
+ // Now perform sensitive operations
735
+ ```
736
+
737
+ #### Re-authenticate with Popup
738
+ ```javascript
739
+ import { reauthenticateWithPopup, GoogleAuthProvider } from 'firebase/auth';
740
+
741
+ const provider = new GoogleAuthProvider();
742
+ await reauthenticateWithPopup(auth.currentUser, provider);
743
+ ```
744
+
745
+ #### Re-authenticate with Redirect
746
+ ```javascript
747
+ import { reauthenticateWithRedirect, GoogleAuthProvider } from 'firebase/auth';
748
+
749
+ const provider = new GoogleAuthProvider();
750
+ await reauthenticateWithRedirect(auth.currentUser, provider);
751
+
752
+ // After redirect
753
+ const result = await getRedirectResult(auth);
754
+ ```
755
+
756
+ #### Re-authenticate with Phone Number
757
+ ```javascript
758
+ import { reauthenticateWithPhoneNumber } from 'firebase/auth';
759
+
760
+ const confirmationResult = await reauthenticateWithPhoneNumber(
761
+ auth.currentUser,
762
+ '+1234567890',
763
+ recaptchaVerifier
764
+ );
765
+
766
+ const verificationCode = '123456';
767
+ await confirmationResult.confirm(verificationCode);
768
+ ```
769
+
770
+ ### Session Persistence
771
+
772
+ #### Set Persistence (Browser)
773
+ ```javascript
774
+ import {
775
+ setPersistence,
776
+ browserLocalPersistence,
777
+ browserSessionPersistence,
778
+ inMemoryPersistence,
779
+ indexedDBLocalPersistence
780
+ } from 'firebase/auth';
781
+
782
+ // Local persistence using localStorage (survives browser restart)
783
+ await setPersistence(auth, browserLocalPersistence);
784
+
785
+ // Session persistence using sessionStorage (survives page refresh only)
786
+ await setPersistence(auth, browserSessionPersistence);
787
+
788
+ // No persistence (memory only)
789
+ await setPersistence(auth, inMemoryPersistence);
790
+
791
+ // IndexedDB persistence (recommended for large data)
792
+ await setPersistence(auth, indexedDBLocalPersistence);
793
+ ```
794
+
795
+ #### React Native Persistence
796
+ ```javascript
797
+ import { initializeAuth, getReactNativePersistence } from 'firebase/auth';
798
+ import AsyncStorage from '@react-native-async-storage/async-storage';
799
+
800
+ const auth = initializeAuth(app, {
801
+ persistence: getReactNativePersistence(AsyncStorage)
802
+ });
803
+ ```
804
+
805
+ #### Cookie Persistence (Public Preview)
806
+ ```javascript
807
+ import { setPersistence, browserCookiePersistence } from 'firebase/auth';
808
+
809
+ // For hybrid rendering and middleware applications
810
+ await setPersistence(auth, browserCookiePersistence);
811
+ ```
812
+
813
+ ### Language and Localization
814
+
815
+ #### Use Device Language
816
+ ```javascript
817
+ import { useDeviceLanguage } from 'firebase/auth';
818
+
819
+ useDeviceLanguage(auth); // Use device language
820
+
821
+ // Or set specific language
822
+ auth.languageCode = 'es';
823
+ ```
824
+
825
+ #### Initialize reCAPTCHA Config
826
+ ```javascript
827
+ import { initializeRecaptchaConfig } from 'firebase/auth';
828
+
829
+ // Load reCAPTCHA config to reduce latency for auth flows
830
+ await initializeRecaptchaConfig(auth);
831
+ ```
832
+
833
+ ### Action Code Handling
834
+
835
+ #### Handle Password Reset Link
836
+ ```javascript
837
+ import { verifyPasswordResetCode, confirmPasswordReset } from 'firebase/auth';
838
+
839
+ const actionCode = 'code-from-email-link';
840
+
841
+ // Verify code is valid
842
+ const email = await verifyPasswordResetCode(auth, actionCode);
843
+
844
+ // Reset password
845
+ await confirmPasswordReset(auth, actionCode, 'newPassword123');
846
+ ```
847
+
848
+ #### Handle Email Verification
849
+ ```javascript
850
+ import { applyActionCode } from 'firebase/auth';
851
+
852
+ const actionCode = 'code-from-email-link';
853
+ await applyActionCode(auth, actionCode);
854
+ ```
855
+
856
+ #### Handle Email Change
857
+ ```javascript
858
+ import { checkActionCode, applyActionCode } from 'firebase/auth';
859
+
860
+ const actionCode = 'code-from-email-link';
861
+ const info = await checkActionCode(auth, actionCode);
862
+ await applyActionCode(auth, actionCode);
863
+ ```
864
+
865
+ #### Parse Action Code URL
866
+ ```javascript
867
+ import { parseActionCodeURL } from 'firebase/auth';
868
+
869
+ const actionCodeUrl = parseActionCodeURL('https://example.com/action?mode=...');
870
+
871
+ if (actionCodeUrl) {
872
+ console.log('Mode:', actionCodeUrl.operation); // 'PASSWORD_RESET', 'VERIFY_EMAIL', etc.
873
+ console.log('Code:', actionCodeUrl.code);
874
+ console.log('Continue URL:', actionCodeUrl.continueUrl);
875
+ console.log('Language:', actionCodeUrl.languageCode);
876
+ }
877
+ ```
878
+
879
+ ### Additional User Info
880
+
881
+ #### Get Provider-Specific Info
882
+ ```javascript
883
+ import { signInWithPopup, GoogleAuthProvider, getAdditionalUserInfo } from 'firebase/auth';
884
+
885
+ const provider = new GoogleAuthProvider();
886
+ const userCredential = await signInWithPopup(auth, provider);
887
+
888
+ const additionalInfo = getAdditionalUserInfo(userCredential);
889
+ console.log('Is new user:', additionalInfo.isNewUser);
890
+ console.log('Provider ID:', additionalInfo.providerId);
891
+ console.log('Profile:', additionalInfo.profile); // Provider-specific profile
892
+ console.log('Username:', additionalInfo.username); // GitHub/Twitter username
893
+ ```
894
+
895
+ ### Revoke Access Tokens
896
+
897
+ #### Revoke Apple OAuth Token
898
+ ```javascript
899
+ import { revokeAccessToken } from 'firebase/auth';
900
+
901
+ // Revoke Apple OAuth access token
902
+ await revokeAccessToken(auth, appleAccessToken);
903
+ ```
904
+
905
+ ## 6. TypeScript Usage
906
+
907
+ ### Import Types
908
+ ```typescript
909
+ import type {
910
+ Auth,
911
+ User,
912
+ UserCredential,
913
+ AuthProvider,
914
+ AuthError,
915
+ IdTokenResult,
916
+ MultiFactorResolver,
917
+ Unsubscribe
918
+ } from 'firebase/auth';
919
+ ```
920
+
921
+ ### Type-Safe User Handling
922
+ ```typescript
923
+ import { onAuthStateChanged, User } from 'firebase/auth';
924
+
925
+ onAuthStateChanged(auth, (user: User | null) => {
926
+ if (user) {
927
+ const uid: string = user.uid;
928
+ const email: string | null = user.email;
929
+ const emailVerified: boolean = user.emailVerified;
930
+ }
931
+ });
932
+ ```
933
+
934
+ ### Type-Safe Error Handling
935
+ ```typescript
936
+ import { signInWithEmailAndPassword, AuthError } from 'firebase/auth';
937
+
938
+ try {
939
+ await signInWithEmailAndPassword(auth, email, password);
940
+ } catch (error) {
941
+ const authError = error as AuthError;
942
+
943
+ switch (authError.code) {
944
+ case 'auth/user-not-found':
945
+ console.error('User not found');
946
+ break;
947
+ case 'auth/wrong-password':
948
+ console.error('Wrong password');
949
+ break;
950
+ case 'auth/invalid-email':
951
+ console.error('Invalid email');
952
+ break;
953
+ default:
954
+ console.error('Authentication error:', authError.message);
955
+ }
956
+ }
957
+ ```
958
+
959
+ ### Custom Claims Type
960
+ ```typescript
961
+ interface CustomClaims {
962
+ admin?: boolean;
963
+ role?: string;
964
+ subscription?: string;
965
+ }
966
+
967
+ const idTokenResult = await user.getIdTokenResult();
968
+ const claims = idTokenResult.claims as CustomClaims;
969
+
970
+ if (claims.admin) {
971
+ console.log('User is an admin');
972
+ }
973
+ ```
974
+
975
+ ## 7. OAuth Credential Handling
976
+
977
+ #### Sign In with OAuth Credential
978
+ ```javascript
979
+ import { signInWithCredential, GoogleAuthProvider } from 'firebase/auth';
980
+
981
+ // Create credential from access token
982
+ const credential = GoogleAuthProvider.credential(idToken, accessToken);
983
+ await signInWithCredential(auth, credential);
984
+ ```
985
+
986
+ #### Extract Credential from Result
987
+ ```javascript
988
+ import { signInWithPopup, GoogleAuthProvider } from 'firebase/auth';
989
+
990
+ const provider = new GoogleAuthProvider();
991
+ const result = await signInWithPopup(auth, provider);
992
+
993
+ // Get OAuth credential from result
994
+ const credential = GoogleAuthProvider.credentialFromResult(result);
995
+ const accessToken = credential.accessToken;
996
+ const idToken = credential.idToken;
997
+ ```
998
+
999
+ #### Extract Credential from Error
1000
+ ```javascript
1001
+ import { signInWithPopup, GoogleAuthProvider } from 'firebase/auth';
1002
+
1003
+ try {
1004
+ await signInWithPopup(auth, provider);
1005
+ } catch (error) {
1006
+ // Extract credential that was being used
1007
+ const credential = GoogleAuthProvider.credentialFromError(error);
1008
+
1009
+ if (error.code === 'auth/account-exists-with-different-credential') {
1010
+ // Handle account linking
1011
+ const methods = await fetchSignInMethodsForEmail(auth, error.customData.email);
1012
+ // Proceed with account linking flow
1013
+ }
1014
+ }
1015
+ ```