I have a cloud function that caches the response from the API. It makes a API request, store result to the firestore. And return the result either from firestore (it it's less than 2 hours left) or from the API.
The code:
const functions = require('firebase-functions');
const admin = require('firebase-admin');
const fetch = require('node-fetch');
const CACHE_DURATION_MS = 2 * 60 * 60 * 1000; // 2 hours in milliseconds
const AWS_API_BASE_URL = 'https://....URL_HERE....';
const APITOKEN = '....TOKEN....';
const REQUEST_TYPE = 'bigdiscounts';
const DB_COLLECTION = '...collection_name...';
const RESULT_LIMIT = '10';
exports.cachedProductsBig = functions.https.onCall(async (data, context) => {
try {
// Get parameters from the data object
const requestType = REQUEST_TYPE; // const requestType = data.requestType;
const authToken = APITOKEN; // const authToken = data.authToken;
// Validate input
if (!requestType || !authToken) {
throw new functions.https.HttpsError(
'invalid-argument',
'Missing required parameters'
);
}
if (!['bigdiscounts', 'newdiscounts'].includes(requestType)) {
throw new functions.https.HttpsError(
'invalid-argument',
'Invalid request_type'
);
}
// Reference to the cache document in Firestore
const cacheRef = admin.firestore()
.collection(DB_COLLECTION)
.doc(requestType);
// Try to get cached data
const cacheDoc = await cacheRef.get();
const now = Date.now();
if (cacheDoc.exists) {
const cacheData = cacheDoc.data();
const cacheAge = now - cacheData.timestamp;
// If cache is fresh, return cached data
if (cacheAge < CACHE_DURATION_MS) {
return cacheData.data;
}
}
// If no cache or cache is stale, fetch from API
const apiResponse = await fetch(
`${AWS_API_BASE_URL}/products/combined?request_type=${requestType}&limit=${RESULT_LIMIT}`,
{
headers: {
'Authorization': authToken
}
}
);
if (!apiResponse.ok) {
throw new functions.https.HttpsError(
'internal',
`API responded with status ${apiResponse.status}`
);
}
const apiData = await apiResponse.json();
// Validate the API response structure
if (!Array.isArray(apiData.items)) {
throw new functions.https.HttpsError(
'internal',
'Invalid API response structure'
);
}
// Store in cache
await cacheRef.set({
data: apiData,
timestamp: now
});
return apiData;
} catch (error) {
console.error('Error in cachedProducts:', error);
throw new functions.https.HttpsError(
'internal',
error.message
);
}
});
It works great when I test my app from FlutterFlow. But, when I downloaded the code and created iOS build - it doesn't work as in FF. I see in Firestore that collection is updated (so the function is triggered), but there is no result In my app - it seems like it returns null. What could be the issue? Why there is a difference between FF and iOS build?