I have a use case where I need to use geofirex library inside Google Cloud Functions. The init function of the library expects FirebaseApp instance. Is it possible to initialise it inside cloud functions in order to query firestore database using firebase-admin?
What i tried..
functions > src > index.ts
import * as functions from 'firebase-functions';
import * as admin from 'firebase-admin';
admin.initializeApp();
admin.firestore().settings({timestampsInSnapshots: true});
// Init GeoFireX
import * as firebase from 'firebase/app';
import * as geofirex from 'geofirex';
const geoFire = geofirex.init(firebase);
exports.geofenceUserNotifications = functions.https.onRequest((req, res) => {
if(!req || !req.body || !req.body.length || !req.body[0].latitude || !req.body[0].longitude || !req.body[0].uid || !req.body[0].userFcmToken){
// end function with 401 status
res.status(401).send('Authentication required.');
}
const uid = req.body[0].uid;
const userFcmToken = req.body[0].userFcmToken;
const latitude = req.body[0].latitude;
const longitude = req.body[0].longitude;
const field = 'position';
geoFire.collection('users').setPoint(uid, field, latitude, longitude).then(result => {
res.end('User geoPoint updated!');
}).catch( err => {
console.log(err);
res.end('error when update user geo point!');
});
});
functions > package.json
{
"name": "functions",
"scripts": {
"lint": "tslint --project tsconfig.json",
"build": "tsc",
"serve": "npm run build && firebase serve --only functions",
"shell": "npm run build && firebase functions:shell",
"start": "npm run shell",
"deploy": "firebase deploy --only functions",
"logs": "firebase functions:log"
},
"main": "lib/index.js",
"dependencies": {
"firebase-admin": "~6.0.0",
"firebase-functions": "^2.1.0",
"moment": "^2.23.0",
"firebase": "^5.10.1",
"geofirex": "0.0.6",
"rxjs": "^6.3.3",
"rxjs-compat": "^6.5.1"
},
"devDependencies": {
"tslint": "~5.8.0",
"typescript": "~2.8.3"
},
"private": true
}
No error when deploy but when call geofenceUserNotifications function i get this error:
TypeError: app.firestore is not a function
at new GeoFireCollectionRef (/user_code/node_modules/geofirex/dist/index.cjs.js:1465:24)
at GeoFireClient.collection (/user_code/node_modules/geofirex/dist/index.cjs.js:1639:16)
at exports.geofenceUserNotifications.functions.https.onRequest (/user_code/lib/index.js:2197:13)
at cloudFunction (/user_code/node_modules/firebase-functions/lib/providers/https.js:57:9)
at /var/tmp/worker/worker.js:783:7
at /var/tmp/worker/worker.js:766:11
at _combinedTickCallback (internal/process/next_tick.js:73:7)
at process._tickDomainCallback (internal/process/next_tick.js:128:9)
Thanks in advance.
the problem solved as following:
const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp();
admin.firestore().settings({timestampsInSnapshots: true});
// Init GeoFireX
const geofirex = require('geofirex');// <-- Use require Instead of import geofirex
import { get } from 'geofirex';
const geoFire = geofirex.init(admin); // <-- admin not admin.app()
Then
exports.geofenceUserNotifications = functions.https.onRequest(async (req, res) => {
//setPoint (id, field, lat, lng)
geoFire.collection('users').setPoint(uid, field, latitude, longitude).then(result => {
res.end('User geo point is updated!');
}).catch( err => {
res.end('error when update user geo point');
return;
});
});
And geoFireX works fine.
but now I faced other problem with geoFireX query.
I tried get nearby items but geoFireX returns Observable<object[]>
and it's not work within cloud functions.
I tried use get() by geoFireX:
const query = geoFire.collection('places', queryRef).within(center, radius, field);
const nearbyPlaces = await get(query); // await query.pipe(operators.first()).toPromise();
but unfortunately it does not work. and I get the following error:
Error: Argument "onNext" is not a valid function. at Validator.(anonymous function).values [as isFunction] (/srv/node_modules/@google-cloud/firestore/build/src/validate.js:99:27) at Query.onSnapshot (/srv/node_modules/@google-cloud/firestore/build/src/reference.js:1524:25) at Observable._subscribe (/srv/node_modules/geofirex/dist/index.cjs.js:1597:33) at Observable._trySubscribe (/srv/node_modules/rxjs/internal/Observable.js:44:25) at Observable.subscribe (/srv/node_modules/rxjs/internal/Observable.js:30:22) at MapOperator.call (/srv/node_modules/rxjs/internal/operators/map.js:32:23) at Observable.subscribe (/srv/node_modules/rxjs/internal/Observable.js:25:31) at Object.subscribeToResult (/srv/node_modules/rxjs/internal/util/subscribeToResult.js:12:23) at CombineLatestSubscriber._complete (/srv/node_modules/rxjs/internal/observable/combineLatest.js:76:46) at CombineLatestSubscriber.Subscriber.complete (/srv/node_modules/rxjs/internal/Subscriber.js:78:18)