evaldoc 1.0.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.
- package/.env.staging.example +19 -0
- package/.firebaserc +6 -0
- package/.github/workflows/auto-merge-to-main.yml +28 -0
- package/.github/workflows/ci.yml +27 -0
- package/.github/workflows/npxhub-publish.yml +170 -0
- package/.prettierignore +4 -0
- package/.prettierrc.json +7 -0
- package/README.md +142 -0
- package/SRS.md +448 -0
- package/apphosting.staging.yaml +48 -0
- package/apphosting.yaml +50 -0
- package/bin/evaldoc.cjs +105 -0
- package/cors.json +8 -0
- package/docs/ARCHITECTURE.md +769 -0
- package/docs/ARCHITECTURE_SUMMARY.md +323 -0
- package/docs/DEPLOYMENT.md +86 -0
- package/docs/DEPLOYMENT_STEPS.md +373 -0
- package/docs/DEPLOY_FIRESTORE_RULES.md +239 -0
- package/docs/DEPLOY_STORAGE_RULES.md +82 -0
- package/docs/DOCTOR_TUTORIAL.md +467 -0
- package/docs/FIREBASE_STORAGE_CORS_FIX.md +131 -0
- package/docs/FIXES_APPLIED.md +128 -0
- package/docs/IMPLEMENTATION.md +498 -0
- package/docs/IMPLEMENTATION_COMPLETE.md +317 -0
- package/docs/LLM-SETUP.md +216 -0
- package/docs/MANUAL_TEST_GUIDE.md +327 -0
- package/docs/PATIENT_GUIDE.md +451 -0
- package/docs/PLATFORM_OVERVIEW.md +194 -0
- package/docs/QUICKSTART.md +252 -0
- package/docs/QUICK_REFERENCE.md +222 -0
- package/docs/READY_TO_TEST.md +383 -0
- package/docs/RUN.md +237 -0
- package/docs/START_TESTING.md +130 -0
- package/docs/STRIPE_CONNECT_SETUP.md +454 -0
- package/docs/SYSTEM_READY.md +345 -0
- package/docs/THREADS_IMPLEMENTATION_COMPLETE.md +431 -0
- package/docs/THREAD_IMPLEMENTATION_GUIDE.md +345 -0
- package/docs/firebasefiles.md +21 -0
- package/docs/homepage.md +1208 -0
- package/docs/payments.md +159 -0
- package/eslint.config.js +76 -0
- package/firebase.json +27 -0
- package/firestore.indexes.json +88 -0
- package/firestore.rules +125 -0
- package/functions/package-lock.json +2884 -0
- package/functions/package.json +20 -0
- package/functions/src/analytics.js +101 -0
- package/functions/src/audit.js +28 -0
- package/functions/src/auth.js +19 -0
- package/functions/src/drafts.js +128 -0
- package/functions/src/feedback.js +164 -0
- package/functions/src/firebase-init.js +29 -0
- package/functions/src/i18n.js +134 -0
- package/functions/src/limits.js +27 -0
- package/functions/src/llm.js +271 -0
- package/functions/src/ner.js +162 -0
- package/functions/src/notifications.js +273 -0
- package/functions/src/orgs.js +127 -0
- package/functions/src/patient-api.js +545 -0
- package/functions/src/payment.js +830 -0
- package/functions/src/safety.js +188 -0
- package/functions/src/stripe-config.js +33 -0
- package/functions/src/topics.js +94 -0
- package/functions/src/triage.js +191 -0
- package/functions/src/utils.js +28 -0
- package/functions/src/validate.js +177 -0
- package/functions/test-firebase.js +36 -0
- package/jest.config.js +18 -0
- package/package.json +52 -0
- package/public/404.html +93 -0
- package/public/app/analytics.html +336 -0
- package/public/app/analytics.js +177 -0
- package/public/app/app.css +1400 -0
- package/public/app/app.js +1754 -0
- package/public/app/config.js +14 -0
- package/public/app/inbox-threads.js +843 -0
- package/public/app/inbox.html +598 -0
- package/public/app/inbox.js +397 -0
- package/public/app/index.html +612 -0
- package/public/assets/logo.jpg +0 -0
- package/public/chat.html +137 -0
- package/public/css/chat.css +870 -0
- package/public/css/landing-enhance.css +298 -0
- package/public/css/styles.css +1198 -0
- package/public/favicon.svg +5 -0
- package/public/find-doctor.html +220 -0
- package/public/index.html +399 -0
- package/public/js/chat-threads.js +513 -0
- package/public/js/chat.js +832 -0
- package/public/js/search.js +41 -0
- package/public/privacy.html +101 -0
- package/public/robots.txt +6 -0
- package/public/site.webmanifest +12 -0
- package/public/terms.html +110 -0
- package/scripts/create-test-provider.js +55 -0
- package/scripts/deploy-staging.sh +51 -0
- package/scripts/fix-provider.js +39 -0
- package/scripts/quick-test.sh +37 -0
- package/scripts/test-chat.sh +54 -0
- package/scripts/test-multi-turn.js +137 -0
- package/scripts/test-ner-simple.js +28 -0
- package/scripts/test-ner.js +60 -0
- package/scripts/test-stripe-connect.js +304 -0
- package/scripts/test-webhook-secret.sh +24 -0
- package/server.js +3864 -0
- package/storage.rules +22 -0
- package/test-api.json +1 -0
- package/tests/emulator/README.md +38 -0
- package/tests/emulator/counters.emulator.test.js +81 -0
- package/tests/integration/api-account-selfserve.test.js +312 -0
- package/tests/integration/api-admin-digest.test.js +202 -0
- package/tests/integration/api-chat-satisfaction.test.js +259 -0
- package/tests/integration/api-doctor-drafts.test.js +236 -0
- package/tests/integration/api-doctor-inbox.test.js +401 -0
- package/tests/integration/api-org.test.js +328 -0
- package/tests/integration/api-payment.test.js +664 -0
- package/tests/integration/api-provider-settings.test.js +475 -0
- package/tests/integration/api-qr.test.js +121 -0
- package/tests/integration/api-security.test.js +241 -0
- package/tests/integration/api-stripe-search.test.js +303 -0
- package/tests/integration/api-webhook-deletion.test.js +231 -0
- package/tests/mocks/firebase-admin.js +220 -0
- package/tests/unit/analytics.test.js +151 -0
- package/tests/unit/audit-bugs.test.js +203 -0
- package/tests/unit/chat-ui-logic.test.js +283 -0
- package/tests/unit/drafts.test.js +104 -0
- package/tests/unit/feedback.test.js +148 -0
- package/tests/unit/i18n.test.js +229 -0
- package/tests/unit/llm-retry.test.js +122 -0
- package/tests/unit/notifications.test.js +155 -0
- package/tests/unit/orgs.test.js +328 -0
- package/tests/unit/payment.test.js +889 -0
- package/tests/unit/safety-edge-cases.test.js +509 -0
- package/tests/unit/safety-srs-compliance.test.js +252 -0
- package/tests/unit/safety.test.js +291 -0
- package/tests/unit/server-helpers.test.js +774 -0
- package/tests/unit/topics-limits.test.js +158 -0
- package/tests/unit/triage.test.js +152 -0
- package/tests/unit/validate.test.js +408 -0
|
@@ -0,0 +1,345 @@
|
|
|
1
|
+
# Thread-Based Conversation System - Implementation Guide
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
This guide covers the implementation of a WhatsApp-style thread-based conversation system where patients can maintain persistent conversations with multiple doctors using Google Sign-In.
|
|
6
|
+
|
|
7
|
+
## Architecture Summary
|
|
8
|
+
|
|
9
|
+
```
|
|
10
|
+
Patient (Google Auth) ←→ Thread ←→ Doctor (Provider)
|
|
11
|
+
↓ ↓ ↓
|
|
12
|
+
patients/ threads/ providers/
|
|
13
|
+
messages (subcollection)
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
## What's Been Created
|
|
17
|
+
|
|
18
|
+
### 1. Frontend Changes
|
|
19
|
+
|
|
20
|
+
#### [public/chat.html](public/chat.html)
|
|
21
|
+
- ✅ Added Google Sign-In modal
|
|
22
|
+
- ✅ Added Firebase Auth scripts
|
|
23
|
+
- ✅ Added user info display in header
|
|
24
|
+
|
|
25
|
+
#### [public/js/chat-threads.js](public/js/chat-threads.js) (NEW)
|
|
26
|
+
- ✅ Google authentication flow
|
|
27
|
+
- ✅ Thread-based messaging
|
|
28
|
+
- ✅ Load conversation history
|
|
29
|
+
- ✅ Real-time message display
|
|
30
|
+
- ✅ Payment integration
|
|
31
|
+
|
|
32
|
+
### 2. Backend Changes
|
|
33
|
+
|
|
34
|
+
#### [functions/src/patient-api.js](functions/src/patient-api.js) (NEW)
|
|
35
|
+
New API endpoints for patients:
|
|
36
|
+
- `GET /api/patient/me` - Get patient profile
|
|
37
|
+
- `POST /api/patient/create` - Create patient profile
|
|
38
|
+
- `POST /api/patient/thread` - Get or create thread with doctor
|
|
39
|
+
- `GET /api/patient/threads` - Get all patient threads
|
|
40
|
+
- `GET /api/patient/thread/:threadId/messages` - Get messages
|
|
41
|
+
- `POST /api/patient/message` - Send message
|
|
42
|
+
- `POST /api/patient/thread/:threadId/read` - Mark as read
|
|
43
|
+
|
|
44
|
+
### 3. Security Rules
|
|
45
|
+
|
|
46
|
+
#### [firestore.rules](firestore.rules)
|
|
47
|
+
- ✅ Added `patients` collection rules
|
|
48
|
+
- ✅ Added `threads` collection rules
|
|
49
|
+
- ✅ Added `messages` subcollection rules
|
|
50
|
+
|
|
51
|
+
## Implementation Steps
|
|
52
|
+
|
|
53
|
+
### Step 1: Enable Google Sign-In in Firebase Console
|
|
54
|
+
|
|
55
|
+
1. Go to Firebase Console → Authentication → Sign-in method
|
|
56
|
+
2. Enable **Google** provider
|
|
57
|
+
3. Add your authorized domains:
|
|
58
|
+
- `localhost` (for testing)
|
|
59
|
+
- Your production domain (e.g., `evaldoc.com`)
|
|
60
|
+
|
|
61
|
+
### Step 2: Update Firebase Functions
|
|
62
|
+
|
|
63
|
+
Add the patient API to your main index.js:
|
|
64
|
+
|
|
65
|
+
```javascript
|
|
66
|
+
// In functions/src/index.js
|
|
67
|
+
const { handlePatientAPI } = require("./patient-api");
|
|
68
|
+
|
|
69
|
+
exports.api = functions
|
|
70
|
+
.runWith({
|
|
71
|
+
secrets: ['GEMINI_API_KEY', 'DEEPSEEK_API_KEY']
|
|
72
|
+
})
|
|
73
|
+
.https.onRequest(async (req, res) => {
|
|
74
|
+
res.set("Access-Control-Allow-Origin", "*");
|
|
75
|
+
res.set("Access-Control-Allow-Methods", "POST, GET, OPTIONS");
|
|
76
|
+
res.set("Access-Control-Allow-Headers", "Content-Type, Authorization");
|
|
77
|
+
|
|
78
|
+
if (req.method === "OPTIONS") {
|
|
79
|
+
res.status(204).send("");
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// ... existing routes ...
|
|
84
|
+
|
|
85
|
+
// Patient API routes
|
|
86
|
+
if (req.path.startsWith("/patient/")) {
|
|
87
|
+
const user = await requireAuth(req, res);
|
|
88
|
+
if (!user) return;
|
|
89
|
+
await handlePatientAPI(req, res, user);
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
// ... rest of routes ...
|
|
94
|
+
});
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
### Step 3: Update chat.html to use new script
|
|
98
|
+
|
|
99
|
+
Change the script tag in [chat.html](public/chat.html:120):
|
|
100
|
+
|
|
101
|
+
```html
|
|
102
|
+
<!-- OLD -->
|
|
103
|
+
<script src="/js/chat.js?v=3"></script>
|
|
104
|
+
|
|
105
|
+
<!-- NEW -->
|
|
106
|
+
<script src="/js/chat-threads.js?v=1"></script>
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
### Step 4: Deploy Firestore Rules
|
|
110
|
+
|
|
111
|
+
```bash
|
|
112
|
+
firebase deploy --only firestore:rules
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
### Step 5: Deploy Functions
|
|
116
|
+
|
|
117
|
+
```bash
|
|
118
|
+
cd functions
|
|
119
|
+
npm install
|
|
120
|
+
cd ..
|
|
121
|
+
firebase deploy --only functions
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
### Step 6: Test the Flow
|
|
125
|
+
|
|
126
|
+
1. Go to `localhost:3000/dr-john-cardiology` (or your doctor's handle)
|
|
127
|
+
2. Try to send a message
|
|
128
|
+
3. Should see "Sign in to continue" modal
|
|
129
|
+
4. Click "Continue with Google"
|
|
130
|
+
5. Sign in with Google account
|
|
131
|
+
6. Message should send and AI should respond
|
|
132
|
+
7. Refresh page - conversation should persist
|
|
133
|
+
|
|
134
|
+
## Data Models
|
|
135
|
+
|
|
136
|
+
### Patient Document
|
|
137
|
+
```javascript
|
|
138
|
+
// firestore: patients/{patientId}
|
|
139
|
+
{
|
|
140
|
+
email: "john@gmail.com",
|
|
141
|
+
displayName: "John Doe",
|
|
142
|
+
photoURL: "https://...",
|
|
143
|
+
doctorIds: ["dr_john", "dr_jane"],
|
|
144
|
+
notificationsEnabled: true,
|
|
145
|
+
fcmToken: null,
|
|
146
|
+
createdAt: Timestamp,
|
|
147
|
+
lastActiveAt: Timestamp
|
|
148
|
+
}
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
### Thread Document
|
|
152
|
+
```javascript
|
|
153
|
+
// firestore: threads/{thread_patientId_doctorId}
|
|
154
|
+
{
|
|
155
|
+
// Patient info
|
|
156
|
+
patientId: "google_uid_xyz",
|
|
157
|
+
patientEmail: "john@gmail.com",
|
|
158
|
+
patientName: "John Doe",
|
|
159
|
+
patientPhoto: "https://...",
|
|
160
|
+
|
|
161
|
+
// Doctor info
|
|
162
|
+
doctorId: "dr_john",
|
|
163
|
+
doctorName: "Dr. John Smith",
|
|
164
|
+
doctorHandle: "dr-john-cardiology",
|
|
165
|
+
|
|
166
|
+
// Status
|
|
167
|
+
status: "active",
|
|
168
|
+
isEscalated: false,
|
|
169
|
+
doctorOverride: false,
|
|
170
|
+
|
|
171
|
+
// Last message
|
|
172
|
+
lastMessageAt: Timestamp,
|
|
173
|
+
lastMessageText: "Thank you...",
|
|
174
|
+
lastMessageRole: "patient",
|
|
175
|
+
|
|
176
|
+
// Counts
|
|
177
|
+
unreadByPatient: 0,
|
|
178
|
+
unreadByDoctor: 2,
|
|
179
|
+
messageCount: 15,
|
|
180
|
+
|
|
181
|
+
// Current
|
|
182
|
+
currentTopic: "medication_info_safety",
|
|
183
|
+
|
|
184
|
+
// Billing
|
|
185
|
+
isPaid: true,
|
|
186
|
+
paymentId: "pi_xxx",
|
|
187
|
+
|
|
188
|
+
createdAt: Timestamp,
|
|
189
|
+
updatedAt: Timestamp
|
|
190
|
+
}
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
### Message Document
|
|
194
|
+
```javascript
|
|
195
|
+
// firestore: threads/{threadId}/messages/{messageId}
|
|
196
|
+
{
|
|
197
|
+
threadId: "thread_googleuid_drjohn",
|
|
198
|
+
role: "patient", // patient, doctor, ai
|
|
199
|
+
message: "Hello doctor...",
|
|
200
|
+
|
|
201
|
+
// Doctor-specific
|
|
202
|
+
isDoctorManual: false,
|
|
203
|
+
doctorUserId: null,
|
|
204
|
+
|
|
205
|
+
// Read status
|
|
206
|
+
readByPatient: true,
|
|
207
|
+
readByDoctor: false,
|
|
208
|
+
|
|
209
|
+
// Safety
|
|
210
|
+
wasFiltered: false,
|
|
211
|
+
isAiGenerated: true,
|
|
212
|
+
|
|
213
|
+
createdAt: Timestamp
|
|
214
|
+
}
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
## Next Steps (TODO)
|
|
218
|
+
|
|
219
|
+
### Phase 2: Doctor Inbox Updates
|
|
220
|
+
|
|
221
|
+
Update [public/app/inbox.html](public/app/inbox.html) and [inbox.js](public/app/inbox.js) to:
|
|
222
|
+
1. Show threads instead of conversations
|
|
223
|
+
2. Group by patient (not sessionId)
|
|
224
|
+
3. Show patient name/email instead of sessionId
|
|
225
|
+
4. Add "Reply" button for manual doctor responses
|
|
226
|
+
|
|
227
|
+
### Phase 3: Doctor Manual Reply
|
|
228
|
+
|
|
229
|
+
Add to inbox:
|
|
230
|
+
```javascript
|
|
231
|
+
// Enable doctor to reply manually
|
|
232
|
+
POST /api/doctor/message
|
|
233
|
+
Body: {
|
|
234
|
+
threadId: "thread_...",
|
|
235
|
+
message: "This is my response",
|
|
236
|
+
override: true // Disable AI for this thread
|
|
237
|
+
}
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
### Phase 4: Web Push Notifications
|
|
241
|
+
|
|
242
|
+
1. Add FCM (Firebase Cloud Messaging) to frontend
|
|
243
|
+
2. Request notification permission
|
|
244
|
+
3. Save FCM token to patient profile
|
|
245
|
+
4. Send notification when new message arrives
|
|
246
|
+
|
|
247
|
+
Example:
|
|
248
|
+
```javascript
|
|
249
|
+
// In patient-api.js, after AI responds
|
|
250
|
+
const patient = await getPatient(thread.patientId);
|
|
251
|
+
if (patient.fcmToken && patient.notificationsEnabled) {
|
|
252
|
+
await admin.messaging().send({
|
|
253
|
+
token: patient.fcmToken,
|
|
254
|
+
notification: {
|
|
255
|
+
title: `New message from ${thread.doctorName}`,
|
|
256
|
+
body: aiResponse.substring(0, 100)
|
|
257
|
+
}
|
|
258
|
+
});
|
|
259
|
+
}
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
## Migration Strategy
|
|
263
|
+
|
|
264
|
+
### Option A: Fresh Start (Recommended)
|
|
265
|
+
- Keep existing `conversations` collection as-is
|
|
266
|
+
- New chats use `threads` system
|
|
267
|
+
- Old conversations remain in old dashboard
|
|
268
|
+
- Clean separation
|
|
269
|
+
|
|
270
|
+
### Option B: Gradual Migration
|
|
271
|
+
- Add migration script to convert conversations → threads
|
|
272
|
+
- Link by email/phone if available
|
|
273
|
+
- Otherwise create anonymous patient profiles
|
|
274
|
+
|
|
275
|
+
## Testing Checklist
|
|
276
|
+
|
|
277
|
+
- [ ] Patient can sign in with Google
|
|
278
|
+
- [ ] Patient profile created on first sign-in
|
|
279
|
+
- [ ] Thread created when sending first message
|
|
280
|
+
- [ ] Messages persist after refresh
|
|
281
|
+
- [ ] AI responds correctly
|
|
282
|
+
- [ ] Escalation works
|
|
283
|
+
- [ ] Payment flow works (if enabled)
|
|
284
|
+
- [ ] Doctor can see threads in inbox
|
|
285
|
+
- [ ] Firestore rules prevent unauthorized access
|
|
286
|
+
|
|
287
|
+
## Troubleshooting
|
|
288
|
+
|
|
289
|
+
### "Unauthorized" error
|
|
290
|
+
- Check Firebase Auth is enabled
|
|
291
|
+
- Verify `Authorization: Bearer <token>` header is sent
|
|
292
|
+
- Check Firestore rules are deployed
|
|
293
|
+
|
|
294
|
+
### Messages not persisting
|
|
295
|
+
- Check Firebase console → Firestore
|
|
296
|
+
- Verify `threads` and `messages` collections exist
|
|
297
|
+
- Check browser console for errors
|
|
298
|
+
|
|
299
|
+
### Google Sign-In not working
|
|
300
|
+
- Verify Google provider is enabled in Firebase Console
|
|
301
|
+
- Check authorized domains include your testing domain
|
|
302
|
+
- Clear browser cache/cookies
|
|
303
|
+
|
|
304
|
+
## Performance Considerations
|
|
305
|
+
|
|
306
|
+
1. **Message pagination**: Currently loads last 50 messages. Add pagination for longer threads.
|
|
307
|
+
2. **Real-time updates**: Use Firestore `onSnapshot()` for live updates instead of polling.
|
|
308
|
+
3. **Indexes**: Create composite indexes for queries:
|
|
309
|
+
```
|
|
310
|
+
threads: (patientId, lastMessageAt DESC)
|
|
311
|
+
threads: (doctorId, lastMessageAt DESC)
|
|
312
|
+
```
|
|
313
|
+
|
|
314
|
+
## Security Notes
|
|
315
|
+
|
|
316
|
+
1. All writes go through backend API (Firestore rules block direct writes)
|
|
317
|
+
2. Patients can only read their own threads
|
|
318
|
+
3. Doctors can only read threads where they are the doctor
|
|
319
|
+
4. Use custom claims for doctor authentication
|
|
320
|
+
5. All messages are authenticated via Firebase Auth
|
|
321
|
+
|
|
322
|
+
## Cost Estimation
|
|
323
|
+
|
|
324
|
+
**Firestore Operations per Chat:**
|
|
325
|
+
- Patient sends message: 3 writes (message, thread update, patient update)
|
|
326
|
+
- AI responds: 2 writes (message, thread update)
|
|
327
|
+
- Load conversation: 1 read (thread) + N reads (messages)
|
|
328
|
+
|
|
329
|
+
**Monthly costs (1000 active users, 10 messages each):**
|
|
330
|
+
- Writes: 50,000 writes = $0.58
|
|
331
|
+
- Reads: 100,000 reads = $0.18
|
|
332
|
+
- Total: ~$0.76/month
|
|
333
|
+
|
|
334
|
+
## Support
|
|
335
|
+
|
|
336
|
+
For questions or issues:
|
|
337
|
+
1. Check Firebase Console logs
|
|
338
|
+
2. Check browser developer console
|
|
339
|
+
3. Review Firestore rules
|
|
340
|
+
4. Test API endpoints with Postman/curl
|
|
341
|
+
|
|
342
|
+
---
|
|
343
|
+
|
|
344
|
+
**Status**: Core implementation complete ✅
|
|
345
|
+
**Next**: Update doctor inbox + manual replies + push notifications
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
// Import the functions you need from the SDKs you need
|
|
2
|
+
import { initializeApp } from "firebase/app";
|
|
3
|
+
import { getAnalytics } from "firebase/analytics";
|
|
4
|
+
// TODO: Add SDKs for Firebase products that you want to use
|
|
5
|
+
// https://firebase.google.com/docs/web/setup#available-libraries
|
|
6
|
+
|
|
7
|
+
// Your web app's Firebase configuration
|
|
8
|
+
// For Firebase JS SDK v7.20.0 and later, measurementId is optional
|
|
9
|
+
const firebaseConfig = {
|
|
10
|
+
apiKey: "AIzaSyCLkOkhDZhB2m9bO-VxNmvI4Y179DhjmcQ",
|
|
11
|
+
authDomain: "evaldocplatform.firebaseapp.com",
|
|
12
|
+
projectId: "evaldocplatform",
|
|
13
|
+
storageBucket: "evaldocplatform.firebasestorage.app",
|
|
14
|
+
messagingSenderId: "1028185105722",
|
|
15
|
+
appId: "1:1028185105722:web:4a306dc90dd8af8b2e9c03",
|
|
16
|
+
measurementId: "G-NPWYSPFSVG"
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
// Initialize Firebase
|
|
20
|
+
const app = initializeApp(firebaseConfig);
|
|
21
|
+
const analytics = getAnalytics(app);
|