Ressource konnte nicht geladen werden: Der Server hat mit dem Status 401 () geantwortet
LGChat.js: 78 Vollständiges Fehlerobjekt: FirebaseError: Die Funktion muss während der Authentifizierung aufgerufen werden.
Es sagt mir, dass ich dafür authentifiziert sein muss. Ich bin jedoch vollständig authentifiziert. Ich bin angemeldet und Firebase Storage ruft die mit dem Konto verknüpften Dokumente ab. Ich weiß also, dass andere Firebase-Dienste funktionieren. Ich habe das Konto gelöscht und neu erstellt, daher weiß ich, dass die Authentifizierung nicht fehlerhaft ist. und die Art und Weise, wie aufrufbare Funktionen funktionieren, ist nach meinem Verständnis, dass Firebase die Token-Funktion auf ihrer Seite übernimmt. Daher hat nichts, was ich zu meinem Code hinzufüge, Einfluss auf das gesendete Token.
Jedes Mal, wenn ich versuche, die Funktion zu verwenden, wird das Token gesendet und Firebase lehnt es dann ab. Ich kann mir nicht vorstellen, dass das Token falsch ist. Es ist die einzige Firebase, die sich selbst von ihrer eigenen Authentifizierung generiert und abruft.
Die LMs haben hauptsächlich Umgebungsprobleme vorgeschlagen. Ich habe alle Vorschläge überprüft. Ich habe außerdem bestätigt, dass ich vollständig beim Google Cloud SDK angemeldet bin.
Hat jemand Erfahrung, die mir eine neue Richtung zur Lösung dieses Problems zeigen könnte? Es scheint so ein dummes Problem zu sein, lol.
Die Fehlermeldung wird in meiner Datei „functions/index.js“ und in einer Datei namens „LGChat“ aufgerufen. Bitte lassen Sie mich wissen, was ich sonst noch senden kann, um hilfreich zu sein. Ich bin neu in diesem Bereich, also gehen Sie davon aus, dass ich nicht weiß, wovon Sie sprechen. Es tut mir auch leid, wenn ich diesen Stackoverflow-Beitrag falsch strukturiert habe.
Ich habe alle potenziellen Umgebungsprobleme sorgfältig durchgegangen.
Ich habe es bestätigt Ich bin bei Google Cloud angemeldet.
Ich habe die Callables-Dokumentation durchgesehen, um sicherzustellen, dass alles korrekt eingerichtet ist.
Ich habe bestätigt Mein gcloud-Geheimnis usw. ist alles korrekt.
Ich habe das bestätigt Andere Firebase-Dienste funktionieren.
Ich habe allen Benutzern Aufrufzugriff gewährt.
Ich lösche meinen Cache bei jedem erneuten Bereitstellungsversuch.
Was habe ich übersehen?
Vielen Dank im Voraus für jede Hilfe.
Screenshot der Fehlermeldungen
LGChat-Datei:
Code: Select all
const processDocument = async () => {
if (!selectedFile || isProcessing || isProcessed || !currentUser) return;
setIsProcessing(true);
setError(null);
setProcessingStatus('Starting processing...');
try {
// Use the already initialized functions instance from above
const processPdfDocument = httpsCallable(functions, 'processPdfDocument', {
timeout: 540000
});
console.log('Processing document with auth:', {
uid: currentUser?.uid,
email: currentUser?.email
});
console.log('Document details being sent:', {
fileId: selectedFile.id,
fileName: selectedFile.name,
fileUrl: selectedFile.url,
userId: currentUser.uid
});
setProcessingStatus('Processing PDF...');
console.log('Processing PDF...');
const result = await processPdfDocument({
fileId: selectedFile.id,
fileName: selectedFile.name,
fileUrl: selectedFile.url,
userId: currentUser.uid
});
console.log('Processing PDF result:', result);
if (result.data?.success) {
setIsProcessed(true);
setProcessingStatus(
`Successfully processed ${result.data.pagesProcessed} pages`
);
} else {
throw new Error(
'Processing failed: ' + (result.data?.error || 'Unknown error')
);
}
} catch (error) {
console.error('Error processing document:', error);
setError(error.message || 'Failed to process document.');
setIsProcessed(false);
setProcessingStatus('Processing failed');
}
};
Code: Select all
// Process PDF
exports.processPdfDocument = onCall(
{
memory: "2GiB",
timeoutSeconds: 540,
cors: true,
enforceAppCheck: false,
secrets: [
"OPENAI_API_KEY",
"PINECONE_API_KEY",
"PINECONE_INDEX_NAME",
"PINECONE_HOST"
]
},
async (request, context) => {
// Log the full context and request for debugging
console.log("[processPdfDocument] Request data:", {
auth: request.auth,
rawRequest: request.rawRequest,
data: request.data
});
console.log("[processPdfDocument] Context:", {
auth: context.auth,
rawRequest: context.rawRequest
});
// Check auth
if (!request.auth) {
console.error("[processPdfDocument] No auth context");
throw new HttpsError(
"unauthenticated",
"The function must be called while authenticated."
);
}
// Verify UID
if (!request.auth.uid) {
console.error("[processPdfDocument] No UID in auth context");
throw new HttpsError(
"unauthenticated",
"Invalid authentication. Please sign in again."
);
}
try {
// Verify the token
const decodedToken = await admin.auth().verifyIdToken(context.auth.token);
console.log("[processPdfDocument] Token verified:", decodedToken.uid);
console.log("[processPdfDocument] Auth context:", {
hasAuth: Boolean(context.auth),
uid: context.auth ? context.auth.uid : null,
token: context.auth ? Boolean(context.auth.token) : false,
app: Boolean(context.app)
});
if (!request.auth || !request.auth.uid) {
console.error("[processPdfDocument] Authentication error: No valid auth context");
throw new HttpsError(
"unauthenticated",
"The function must be called while authenticated."
);
}
try {
console.log("[processPdfDocument] Request data:", {
...request.data,
auth: {uid: context.auth.uid}
});
const {fileId, fileName, path} = request.data;
const uid = context.auth.uid;
// Validate parameters with detailed logging
const missingParams = [];
if (!fileId) missingParams.push("fileId");
if (!fileName) missingParams.push("fileName");
if (!path) missingParams.push("path");
if (missingParams.length > 0) {
const errorMsg = `Missing required parameters: ${missingParams.join(", ")}`;
console.error("[processPdfDocument] Parameter validation failed:", {
received: {fileId, fileName, path},
missing: missingParams
});
throw new HttpsError("invalid-argument", errorMsg);
}
// Validate config with error handling
let config;
try {
config = getConfig();
console.log("[processPdfDocument] Configuration validated successfully");
} catch (configError) {
console.error("[processPdfDocument] Configuration error:", configError);
throw new HttpsError(
"failed-precondition",
`Configuration error: ${configError.message}`
);
}
// Initialize storage and get file
const storage = getStorage();
const bucket = storage.bucket();
const tempFilePath = `/tmp/${fileId}-${Date.now()}.pdf`;
// Download file with detailed error handling
try {
console.log("[processPdfDocument] Attempting to download file:", {path, tempFilePath});
await bucket.file(path).download({destination: tempFilePath});
console.log("[processPdfDocument] File downloaded successfully");
} catch (downloadError) {
console.error("[processPdfDocument] Download error:", {
error: downloadError,
path,
tempFilePath
});
throw new HttpsError(
"internal",
`Failed to download file: ${downloadError.message}`
);
}
// Process PDF with error handling
let pdfContent;
try {
const dataBuffer = await fs.readFile(tempFilePath);
console.log("[processPdfDocument] File read successfully, size:", dataBuffer.length);
pdfContent = await pdf(dataBuffer, {
pageNumbers: true,
normalizeWhitespace: true,
disableCombineTextItems: false
});
console.log("[processPdfDocument] PDF parsed successfully, pages:", pdfContent.numpages);
} catch (pdfError) {
console.error("[processPdfDocument] PDF processing error:", pdfError);
throw new HttpsError(
"internal",
`Failed to process PDF: ${pdfError.message}`
);
}
// Create text chunks
const splitter = new RecursiveCharacterTextSplitter({
chunkSize: 1000,
chunkOverlap: 200
});
let allDocs = [];
try {
const docs = await splitter.createDocuments(
[pdfContent.text],
[{
pageNumber: 1,
fileId,
fileName,
userId: uid
}]
);
allDocs = docs;
console.log("[processPdfDocument] Created chunks:", allDocs.length);
} catch (splitError) {
console.error("[processPdfDocument] Text splitting error:", splitError);
throw new HttpsError(
"internal",
`Failed to split text: ${splitError.message}`
);
}
// Initialize Pinecone with error handling
let pineconeIndex;
try {
const pineconeOptions = {
apiKey: config.pineconeApiKey
};
if (config.pineconeHost) {
pineconeOptions.controllerHostUrl = config.pineconeHost;
}
const pinecone = new Pinecone(pineconeOptions);
pineconeIndex = pinecone.index(config.pineconeIndexName);
console.log("[processPdfDocument] Pinecone initialized successfully");
} catch (pineconeError) {
console.error("[processPdfDocument] Pinecone initialization error:", pineconeError);
throw new HttpsError(
"internal",
`Failed to initialize Pinecone: ${pineconeError.message}`
);
}
// Create and store embeddings
try {
const embeddings = new OpenAIEmbeddings({
openAIApiKey: config.openaiApiKey,
batchSize: 100
});
await PineconeStore.fromDocuments(allDocs, embeddings, {
pineconeIndex,
namespace: uid,
maxConcurrency: 5
});
console.log("[processPdfDocument] Documents stored in Pinecone successfully");
} catch (embeddingError) {
console.error("[processPdfDocument] Embedding/storage error:", embeddingError);
throw new HttpsError(
"internal",
`Failed to create/store embeddings: ${embeddingError.message}`
);
}
// Cleanup temp files
try {
await fs.unlink(tempFilePath);
console.log("[processPdfDocument] Cleaned up temporary file");
} catch (cleanupError) {
console.warn("[processPdfDocument] Cleanup warning:", cleanupError);
// Don't throw on cleanup errors
}
return {
success: true,
chunksProcessed: allDocs.length,
pagesProcessed: pdfContent.numpages || 1
};
} catch (error) {
console.error("[processPdfDocument] Top-level error:", {
message: error.message,
code: error.code,
stack: error.stack
});
if (error instanceof HttpsError) {
throw error;
}
throw new HttpsError(
"internal",
`Processing failed: ${error.message}`
);
}
} catch (error) {
console.error("[processPdfDocument] Token verification failed:", error);
throw new HttpsError(
"unauthenticated",
"Invalid authentication token. Please sign in again."
);
}
}
);