Skip to content

Commit 00969c2

Browse files
committed
Implement dedicated document upload function and update prediction handling in SimplifiedUploader component
1 parent d0f05c5 commit 00969c2

File tree

2 files changed

+109
-11
lines changed

2 files changed

+109
-11
lines changed

frontend/src/components/SimplifiedUploader.tsx

Lines changed: 28 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,15 @@ interface Prediction {
77
reasoning: string;
88
}
99

10+
interface PredictionResponse {
11+
success: boolean;
12+
prediction?: {
13+
grade: number | string;
14+
reasoning: string;
15+
};
16+
message?: string;
17+
}
18+
1019
const SimplifiedUploader: React.FC = () => {
1120
const { currentUser } = useAuth();
1221
const [file, setFile] = useState<File | null>(null);
@@ -46,24 +55,34 @@ const SimplifiedUploader: React.FC = () => {
4655
const base64String = fileReader.result as string;
4756

4857
try {
49-
// Use predictGrades function for both upload and prediction
50-
const predictGrades = httpsCallable(functions, 'predictGrades');
51-
const result = await predictGrades({
58+
// Use dedicated upload function
59+
const uploadDocument = httpsCallable(functions, 'uploadDocument');
60+
const result = await uploadDocument({
5261
documentType: documentType,
5362
documentBase64: base64String
5463
});
5564

5665
const data = result.data as any;
5766

5867
if (data.success) {
59-
setStatus('Document uploaded successfully. Processing...');
68+
setStatus('Document uploaded successfully.');
6069

61-
if (data.prediction) {
62-
setPrediction({
63-
grade: data.prediction.grade,
64-
reasoning: data.prediction.reasoning
65-
});
70+
// After successful upload, call predictGrades
71+
try {
72+
const predictGrades = httpsCallable(functions, 'predictGrades');
73+
const predictionResult = await predictGrades({}) as { data: PredictionResponse };
74+
75+
if (predictionResult.data.success && predictionResult.data.prediction) {
76+
setPrediction({
77+
grade: predictionResult.data.prediction.grade,
78+
reasoning: predictionResult.data.prediction.reasoning || 'No reasoning provided'
79+
});
80+
}
81+
} catch (predictionError: any) {
82+
console.error('Prediction error:', predictionError);
83+
// Don't show prediction errors to user, just log them
6684
}
85+
6786
setStatus('');
6887
setIsUploading(false);
6988
} else {

functions-node/index.js

Lines changed: 81 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,85 @@ const OpenAI = require('openai');
88
// Initialize Firebase Admin
99
admin.initializeApp();
1010

11+
/**
12+
* Dedicated function for handling PDF document uploads
13+
*/
14+
exports.uploadDocument = functions.https.onCall(async (data, context) => {
15+
try {
16+
console.log('uploadDocument called with document type:', data.documentType);
17+
18+
// Ensure user is authenticated
19+
if (!context.auth) {
20+
throw new functions.https.HttpsError('unauthenticated', 'User must be authenticated');
21+
}
22+
23+
const userId = context.auth.uid;
24+
25+
// Validate input
26+
if (!data.documentBase64 || !data.documentType) {
27+
throw new functions.https.HttpsError('invalid-argument', 'Missing document data or type');
28+
}
29+
30+
// Process base64 data - handle different formats of base64 strings
31+
let base64Data = data.documentBase64;
32+
if (base64Data.includes('base64,')) {
33+
base64Data = base64Data.split('base64,')[1];
34+
}
35+
36+
// Create buffer from base64
37+
const buffer = Buffer.from(base64Data, 'base64');
38+
console.log(`Created buffer with ${buffer.length} bytes`);
39+
40+
// Create temp file
41+
const tempFile = tmp.fileSync({ postfix: '.pdf' });
42+
fs.writeFileSync(tempFile.name, buffer);
43+
console.log(`Wrote buffer to temp file: ${tempFile.name}`);
44+
45+
try {
46+
// Get default bucket
47+
const bucket = admin.storage().bucket();
48+
const filePath = `users/${userId}/${data.documentType}/${Date.now()}.pdf`;
49+
50+
console.log(`Uploading to Firebase Storage: ${filePath}`);
51+
await bucket.upload(tempFile.name, {
52+
destination: filePath,
53+
metadata: {
54+
contentType: 'application/pdf'
55+
}
56+
});
57+
58+
console.log(`Successfully uploaded to ${filePath}`);
59+
60+
// Store reference in Firestore
61+
const db = admin.firestore();
62+
const docRef = db.collection('users').doc(userId).collection('documents').doc(data.documentType);
63+
64+
await docRef.set({
65+
filePath: filePath,
66+
uploadedAt: admin.firestore.FieldValue.serverTimestamp(),
67+
status: 'uploaded'
68+
});
69+
70+
console.log(`Firestore document updated for ${filePath}`);
71+
72+
return {
73+
success: true,
74+
message: 'Document uploaded successfully',
75+
filePath: filePath
76+
};
77+
} catch (uploadError) {
78+
console.error('Error during upload:', uploadError);
79+
throw new functions.https.HttpsError('internal', `Storage upload failed: ${uploadError.message}`);
80+
} finally {
81+
// Clean up temp file
82+
tempFile.removeCallback();
83+
}
84+
} catch (error) {
85+
console.error('Error in uploadDocument:', error);
86+
throw new functions.https.HttpsError('internal', `Upload failed: ${error.message}`);
87+
}
88+
});
89+
1190
// Get OpenAI API key from Firebase configuration or environment variable
1291
function getOpenAIApiKey() {
1392
const apiKey = process.env.OPENAI_API_KEY ||
@@ -191,7 +270,7 @@ exports.predictGrades = functions.https.onCall(async (data, context) => {
191270
fs.writeFileSync(tempFile.name, buffer);
192271

193272
// Upload to Firebase Storage
194-
const bucket = admin.storage().bucket('gradingai.appspot.com');
273+
const bucket = admin.storage().bucket();
195274
const filePath = `users/${userId}/${data.documentType}/${Date.now()}.pdf`;
196275

197276
await bucket.upload(tempFile.name, {
@@ -320,7 +399,7 @@ async function extractTextFromPdf(userId, documentType, filePath) {
320399
console.log(`Extracting text from ${documentType} PDF: ${filePath} for user ${userId}`);
321400

322401
// Get a reference to the default bucket
323-
const bucket = admin.storage().bucket('gradingai.appspot.com');
402+
const bucket = admin.storage().bucket();
324403
console.log(`Using bucket: ${bucket.name}`);
325404

326405
let tempFile = null;

0 commit comments

Comments
 (0)