AngularFire stopped reporting performance data to Firebase - firebase

I'm using Firebase 9.10.0 with AngularFire 7.4.1 in my project and trying to get performance measurements using Firebase Performance, but for some weird reason, my app does not report any data to Firebase after 9 days of working fine.
import { provideFirebaseApp, initializeApp } from "#angular/fire/app";
import { getPerformance, providePerformance } from "#angular/fire/performance";
#NgModule({
...
imports: [
...
provideFirebaseApp(() => initializeApp(environment.firebase)),
providePerformance(() => (environment.production ? getPerformance() : undefined)),
],
...
})
export class AppModule {}
I checked and verified that the environment check evaluates to prod, so that shouldn't be the root-cause.
As you can see, the report was working between 11. and 20. of October, but then it just stopped without any significant modification in either my code or the Firebase settings. Checking the Network activity, I can't even see requests towards firebaselogging.googleapis.com, so I assume there's something wrong with the client, and not the receiving end.

Related

NextJS and deploying app - What's the use of the /api folder when wanting to make API calls in production (deployed)?

I just went through the steps of creating a CRUD app with NextJS. Everything works fine when I run the app on my development environment npm run dev.
Then I tried to deploy it to Vercel.
The build fails, and the error that comes up is:
AxiosError: connect ECONNREFUSED 127.0.0.1:3000
...
Build error occurred
Error: Failed to collect page data for /beers/[id]
at /vercel/path0/node_modules/next/dist/build/utils.js:963:15
at process.processTicksAndRejections (node:internal/process/task_queues:95:5) {
type: 'Error'
I get it: when I make my API requests, the app is using HTTP:localhost:3000, so if deployed, it won't reach.
Then comes my question: locally, I run requests as such, for example:
import axios from 'axios';
axios.defaults.baseURL = "http://localhost:3000";
export const getAllBeers = () => axios.get<BeerData[]>('/api/beers');
and everything works.
I tried to troubleshoot my error. I figured I needed to adjust my baseUrl to the deployment server's address. But it still wouldn't work. And then in the few posts I read, and even in the docs, it says:
Write server-side code directly
As getStaticProps runs only on the server-side, it will never run on
the client-side. It won’t even be included in the JS bundle for the
browser, so you can write direct database queries without them being
sent to browsers.
This means that instead of fetching an API route from getStaticProps
(that itself fetches data from an external source), you can write the
server-side code directly in getStaticProps.
doc source
So after following their tutorial, I'm now confused on the purpose of this /api folder, and in which specific case it's useful? When we want to use the getStaticProps for example.
If anybody could explain with an example? That'd be fantastic. Thank you!

Firestore has already been started and cannot be changed - Nuxt 2, Firebase Emulator

EDIT (ANSWER): There were two issues with my code. One was that I was passing "http://localhost" instead of just "localhost" to the connectFirestoreEmulator line. The second was that I needed to check db._settingsFrozen before running the emulator line in order to prevent it from being double-initialized. I believe this has something to do with how Nuxt runs its code on the server side vs client side: I think Nuxt shares context/state across sessions on the server side, leading to the emulator line getting run more than once.
I have a Nuxt 2 app that I've connected to Firebase production successfully for a while now. I'm trying to set it up now to use the emulator instead of production when in local environment (indicated by an env variable), but I'm getting an error with the Firebase module specifically. There doesn't seem to be any issues using the auth emulator (which I've also set up). Code (plugins/firebase.js):
const app = initializeApp(firebaseConfig);
const auth = getAuth(app);
const db = getFirestore(app);
export const services = { auth, db };
export default (context) => {
if (context.env.appEnv === 'dev') {
console.log('dev', parseInt(context.env.firestorePort))
connectFirestoreEmulator(db, 'http://localhost', parseInt(context.env.firestorePort));
connectAuthEmulator(auth, `http://localhost:${context.env.authPort}`);
}
}
I have narrowed it down to the "connectFirestoreEmulator" line which when commented out, there are no errors. When it's included, this is the error I get:
Firestore has already been started and its settings can no longer be changed. You can only modify settings before calling any other methods on a Firestore object.
Finally, when I set the plugin to run on client-side only, it no longer errors out which is odd. I'll probably just keep working with this client-only for now, but I would like to be able to run the firebase stuff on the server too ideally.
Any ideas/guidance is appreciated. Thanks in advance!
I've Googled the relevant terms and found one other question that was similar to my question ("Firebase Error : Firestore has already been started and its settings can no longer be changed." connecting Firebase v9 with Firestore Emulator). However, because I don't have enough reputation on SO, I can't comment to ask the OP if he ever found out what was happening (which I would normally do before asking my own question, but I'm not being given a choice here).
I also even looked at the nuxt-firebase npm package's source code (https://github.com/nuxt-community/firebase-module) to see how they may have set up the emulator, but their plugin/code is written so differently from mine that it was unhelpful.

Can't create unit test with FireStore for flutterfire, throws during init, even with simplest possible test

// ignore_for_file: avoid_print
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:flutter_test/flutter_test.dart';
void main() {
group('core tests - coffee', () {
test('fetch coffees', () async {
await Firebase.initializeApp();
final FirebaseFirestore firestore = FirebaseFirestore.instance;
print('initialized');
expect(firestore, isNotNull);
});
});
}
This is in a test. Oddly, it works in the live app, but not in a simple test case.
Errors during Firebase.initializeApp() with:
Null check operator used on a null value
MethodChannel.binaryMessenger
package:flutter/…/services/platform_channel.dart:121
I don't want a testWidgets. I don't want a mocked FireStore. I want to hit the real database.
I'm on a mac, running a simulator, using VSC, although the simulator shouldn't even be involved.
Firebase plugins wraps around native platform (firebase) SDKs and i think they are not available on when running tests.
I would suggest to use either the emulator suite or fake_cloud_firestore package, or do manual testing by humans (connected with a different firebase instance)

firebase scheduled cloud function not being called [duplicate]

I am working on cloud functions especially schedule functions. I need to trigger a function periodically each 5 minutes, but in only test step. I need to run it on pubsub emulator without deploying it.
How to do it?
I tried to use firebase shell, but it triggered only once
exports.scheduledFunctionPlainEnglish =functions.pubsub.schedule('every 2 minutes')
.onRun((context) => {
functions.logger.log("this runs every 2 minutes")
return null;
})
Scheduled functions are loaded to the Cloud Functions emulator runtime and are bound to the PubSub emulator topic.
But as #samstern said (https://github.com/firebase/firebase-tools/issues/2034):
you'd have to manually trigger them using a Pub/Sub message.
You can do it like this:
import * as functions from 'firebase-functions';
import * as admin from 'firebase-admin';
import { PubSub } from '#google-cloud/pubsub';
if (!admin.apps.length) {
admin.initializeApp();
}
const pubsub = new PubSub({
apiEndpoint: 'localhost:8085' // Change it to your PubSub emulator address and port
});
setInterval(() => {
const SCHEDULED_FUNCTION_TOPIC = 'firebase-schedule-yourFunctionName';
console.log(`Trigger sheduled function via PubSub topic: ${SCHEDULED_FUNCTION_TOPIC}`);
const msg = await pubsub.topic(SCHEDULED_FUNCTION_TOPIC).publishJSON({
foo: 'bar',
}, { attr1: 'value1' });
}, 5 * 60 * 1000); // every 5 minutes
Additional info about this concept (thanks to #kthaas):
https://github.com/firebase/firebase-tools/pull/2011/files#diff-6b2a373d8dc24c4074ee623d433662831cadc7c178373fb957c06bc12c44ba7b
https://github.com/firebase/firebase-tools/pull/2011/files#diff-73f0f0ab73ffbf988f109e0a4c8b3b8a793f30ef33929928a892d605f0f0cc1f
As you said, you can use firebase shell to run your function once.
And in firebase shell, you can use NodeJS commands.
Use setInterval
Inside firebase functions:shell, use setInterval to run your function every 2 minutes.
user#laptop:~$ firebase functions:shell
✔ functions: functions emulator started at http://localhost:5000
i functions: Loaded functions: myScheduledFunction
firebase > setInterval(() => myScheduledFunction(), 120000)
> this runs every 2 minutes
Single line script
Since version 8.4.3 of firebase-tools, and especially this PR, the pipe solution does not work anymore.
In Bash, you can even pipe the setInterval command to firebase shell
user#laptop:~$ echo "setInterval(() => myScheduledFunction(), 120000)" | firebase functions:shell
For those of you seeing this in 2023, it's still not supported.
My solution was to abstract the code that does the "work" out of functions.pubsub.schedule and into their own functions. Then create a separate file (i added it at the top of the functions folder) with a setInterval inside it that fires the aforementioned abstracted function.
For example, somewhere in your code:
exports.myScheduledFunctionCode = () => {
console.log('why, hello there interval');
}
And in the timers.js (for example) file at the top of the /functions directory:
setInterval(() => {
myScheduledFunctionCode();
}, 60000);
Then, you can fire up your Firebase Emulator suite. In another Terminal session, just run a vanilla $ node functions/timers.js. Now your scheduled function code is running, and your whole emulator suite too.
Hope this helps someone!
This is currently not supported for scheduled functions. The documentation states:
Using the shell, you mock data and perform function calls to simulate interaction with products that the Emulator Suite does not currently support: Storage, PubSub, Analytics, Remote Config, Storage, Auth, and Crashlytics.
Scheduled functions are an unsupported extension of pubsub triggers.
Feel free to file a feature request with Firebase support.

Unsupported Firebase Functions services?

I'm attempting to deploy a minimal Firebase Function based on an authentication trigger. I've worked successfully before with https and database triggers but I'm getting an error while deploying an authentication trigger (docs, reference).
import * as functions from 'firebase-functions';
import * as admin from 'firebase-admin';
admin.initializeApp();
exports.onCreateUser = functions
.region('europe-west1')
.auth.user()
.onCreate((user: admin.auth.UserRecord, context: functions.EventContext) => {
console.log(`Triggered On Create User: ${user.email}, ${user.uid}.`);
});
I receive the following error:
Ignoring trigger "onCreateUser" because the service "firebaseauth.googleapis.com" is not yet supported.
I've tried changing my engine node version from 10 to 8 or changing the region to europe-west2 or us-central1 but any variations on my configuration would throw this error.
The documentation I've referenced does not mention a limited support for these triggers. Is there any page with an overview of unsupported services and their limitations?
I seem to have mixed up my intent to run serve and deploy here. As I have been told by a very responsive support team the serve script spins up the emulator and is currently limited to the following scopes:
Functions
Firestore
Realtime Database
Hosting
For the development phase, however, you can make use of the interactive shell:
$ firebase functions:shell
✔  functions: Emulator started at http://localhost:5001
i  functions: Loaded functions: onCreateUser
firebase > onCreateUser({"uid":"99999","email":"test#testing.com"})
'Successfully invoked function.'
>  Triggered On Create User: test#testing.com, 99999.
>  Function returned undefined, expected Promise or value

Resources