I'm working on a React Native application where I need to send two images to an API for face comparison. One image is stored in Firebase storage or Firestore, and the other is captured using Expo Camera. However, the API doesn't seem to understand the payload, and I suspect it might be an issue with the format in which the images are sent.
Facial register:
const handleUpload = async () => {
const auth = getAuth();
const user = auth.currentUser;
if (user && lastPhotoURI) {
try {
setUploading(true);
const storage = getStorage();
const imageRef = ref(
storage,
`userData/${user.uid}/${user.email}/Facial/${user.displayName}.jpg`
);
const response = await fetch(lastPhotoURI);
const blob = await response.blob();
await uploadBytes(imageRef, blob);
const downloadURL = await getDownloadURL(imageRef);
// Create a new document in the "userdata" collection with form data and image URL
const db = getFirestore();
const userRef = doc(db, "UsersData", user.uid);
const userDataRef = collection(userRef, "FacialImages");
await setDoc(userRef, {});
const userDocRef = await addDoc(userDataRef, {
email: user.email,
userId: user.uid,
userName: user.displayName,
facialImages: [
{
images: downloadURL,
},
],
});
console.log("Image uploaded successfully. Download URL:", downloadURL);
console.log("Firestore document added with ID:", userDocRef.id);
setUploadSuccess(true);
Alert.alert("Success", "Facial Record Added!");
} catch (error) {
Alert.alert("Error", "Error on Adding Facial Record!");
console.error("Image upload error:", error);
} finally {
setUploading(false);
}
} else {
console.error("User not authenticated or no image to upl/oa/d");
}
};
//Take picture:
<TouchableOpacity
style={{
flex: 0.2,
alignSelf: "flex-end",
alignItems: "center",
justifyContent: "center",
backgroundColor: "#666",
marginBottom: 40,
marginLeft: 20,
}}
onPress={async () => {
if (cameraRef.current) {
let photo = await cameraRef.current.takePictureAsync({
quality: 1,
});
setLastPhotoURI(photo.uri);
}
}}
>
<Text style={{ fontSize: 30, padding: 10, color: "white" }}></Text>
</TouchableOpacity>
// compare uploaded photo to new captured photo
const handleAuthentication = async () => {
try {
// Fetch the second photo URL from Firestore
const auth = getAuth();
const user = auth.currentUser;
if (user) {
const db = getFirestore();
const userRef = doc(db, "UsersData", user.uid);
const userDataRef = collection(userRef, "FacialImages");
try {
const querySnapshot = await getDocs(userDataRef);
if (!querySnapshot.empty) {
const document = querySnapshot.docs[0].data();
const image2URL = document.facialImages[0].images;
console.log("Image2URL fetched successfully:", image2URL);
console.log("lastPhotoURI:", lastPhotoURI);
// Download the image from URL
const down = await fetch(image2URL);
const image2Data = await down.blob();
console.log("Image2Data: ", image2Data);
// Convert blob data to base64
const buffer = await new Response(image2Data).arrayBuffer();
const uint8Array = new Uint8Array(buffer);
const image2Base64 = base64js.fromByteArray(uint8Array);
const requestBody = {
image1Data: lastPhotoURI,
image2Data: image2Base64,
};
const options = {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-BLOBR-KEY': 'mubAKvdrupZP93nWkw79aUHkNMSFiaPK',
},
body: JSON.stringify(requestBody),
};
const response1 = await fetch('http://192.168.0.103:3000/compare_faces', options);
const result1 = await response1.text();
console.log(result1);
} else {
console.error("No facial images found in Firestore.");
}
} catch (error) {
console.error("Error fetching facial images from Firestore:", error);
}
}
} catch (error) {
console.error("Authentication error:", error);
} finally {
setUploading(false);
}
};
LOG Image2URL fetched successfully: https://firebasestorage.googleapis.com/v0/b/protecta-ca1ba.appspot.com/o/userData%2F15E8sM0ExeUi0GzXQsTVVh4emzf2%2Fanashassan517%40gmail.com%2FFacial%2FUehsh.jpg?alt=media&token=8d0d6064-6741-46e8-aa56-15553ce20b75
LOG lastPhotoURI: file:///data/user/0/host.exp.exponent/cache/ExperienceData/%2540anonymous%252Fexpo-template-tabs-689496aa-8aaa-4d64-8441-700a3a4a6570/Camera/1756f17f-af5f-4e18-ac9e-e880284309f1.jpg
LOG Image2Data: {"_data": {"__collector": {}, "blobId": "60ab6d38-e474-4b1a-afc7-0edd61454efa", "offset": 0, "size": 1931073}}
Server:
const axios = require('axios');
const express = require('express');
const bodyParser = require('body-parser');
const app = express();
app.use(express.json({ limit: '10mb' }));
app.use(express.urlencoded({ limit: '10mb', extended: true }));
const port = 3000;
app.use(bodyParser.json());
app.post('/compare_faces', async (req, res) => {
try {
const { image1, image2 } = req.body;
const formData = new FormData();
formData.append('image1', image1);
formData.append('image2', image2);
const options = {
method: 'POST',
headers: {
'X-BLOBR-KEY': 'mubAKvdrupZP93nWkw79aUHkNMSFiaPK',
},
body: formData,
};
fetch('https://api.faceonlive.com/sntzbspfsdupgid1/api/face_compare', options)
.then(response => response.text())
.then(response => console.log(response))
.catch(err => console.error(err));
} catch (error) {
console.error(error);
res.status(500).json({ error: 'Internal server error' });
}
});
app.listen(port, () => {
console.log(`Server is running on port ${port}`);
});
Server Log:
<!doctype html>
<html lang=en>
<title>400 Bad Request</title>
<h1>Bad Request</h1>
<p>The browser (or proxy) sent a request that this server could not understand.</p>
Server calls the API:(https://getapi.faceonlive.com/)
What I Tried:
- Capturing an image using Expo Camera and storing its URI (lastPhotoURI).
- Fetching a stored image URL from Firestore and converting it to base64 (image2Base64).
- Sending both images to the API using a POST request.
Expected Outcome: I expected the API to successfully compare the two images and return the result.