Do Firebase Scheduled Functions run automatically on the emulator? - firebase

I am trying to build a scheduled function on Firebase using the emulator. I've set things up as shown and have verified that PubSub is running on my emulator. However, nothing happens.
I have the following function:
exports.scheduledFunction = functions.pubsub.schedule('every 5 minutes').onRun((context) => {
console.log('This will be run every 5 minutes!');
return null;
});
I can verify the function works using firebase functions:shell:
firebase functions:shell
i functions: Loaded functions: createUserDocument, newSlackUserNotify, scheduledFunction
⚠ functions: The following emulators are not running, calls to these services will affect production: firestore, database, pubsub, storage, eventarc
firebase > scheduledFunction()
'Successfully invoked function.'
firebase > > This will be run every 5 minutes!
My firebase.json:
{
"firestore": {
"rules": "firestore.rules",
"indexes": "firestore.indexes.json"
},
"emulators": {
"auth": {
"port": 9099,
"host": "0.0.0.0"
},
"firestore": {
"port": 8080,
"host": "0.0.0.0"
},
"functions": {
"port": 5001,
"host": "0.0.0.0"
},
"pubsub": {
"port": 8085,
"host": "0.0.0.0"
},
"ui": {
"enabled": true
},
"singleProjectMode": true
},
"functions": [
{
"source": "apps/functions",
"codebase": "default",
"ignore": ["node_modules", ".git", "firebase-debug.log", "firebase-debug.*.log"],
}
]
}
I can see here that someone suggests using a trigger, but shouldn't scheduled functions "just work"?
I have also verified that the scheduled function works when deployed, so this seems to be an emulator-specific thing.
The only possible thing is that SLF4J seems to have not loaded, per pubsub-debug.log:
This is the Google Pub/Sub fake.
Implementation may be incomplete or differ from the real system.
Jan 13, 2023 2:09:25 PM com.google.cloud.pubsub.testing.v1.Main main
INFO: IAM integration is disabled. IAM policy methods and ACL checks are not supported
SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
Jan 13, 2023 2:09:26 PM com.google.cloud.pubsub.testing.v1.Main main
INFO: Server started, listening on 8085
Jan 13, 2023 2:09:31 PM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
INFO: Detected HTTP/2 connection.

As Chris mentioned in above comment.Emulator doesn't support scheduled functions yet. There is a feature request raised for Support for scheduled functions in emulator in github. You can also add your concern over there. You need to trigger them manually using the firebase functions:shell command .You can run the scheduled functions on a interval:
firebase > setInterval(() => yourScheduledFunc(), 60000)
//This will run your functions every 60 seconds.
You can also check this stackoverflow thread1 & thread2

Related

Why Local Firestore Emulator doesn't react to the trigger?

I have this block of code in my /functions/src/index.ts:
export const onAddReviewerSendEmailNotification = functions
.runWith({
timeoutSeconds: 15,
})
.firestore.document("records/{email}/managedByOthers/{reviewerEmail}")
.onWrite( (snap, context) => {
functions.logger.info("something changed!");
functions.logger.debug(`Running add reviewer trigger for userId: ${context.params.email}, reviewerId: ${context.params.reviewerEmail}`);
});
I compile it using npm run build in the functions directory. Then I run the emulator using this command:
firebase emulators:start --only firestore,storage,functions --import test-data
This is what I get:
I can see emulator UI is running. I go to firestore and add a record in this path: records/{email}/managedByOthers/{reviewerEmail}. Then I go to emulator's Logs section. Nothing has been logged. Am I doing something wrong?
I finally found the solution after wasting 4 hours on the issue. I replaced
"functions": {
"port": 5001
},
by
"functions": {
"host": "0.0.0.0",
"port": 5001
},
in the firebase.json file. I am able to see the logs now!

Swiftui and firebase emulators not working on physical device / simulator

I am working on a swiftui app and just started using the Emulator suite of firebase.
Everything is fine when i preview the app and write to a firestore collection or authenticate a user. The problem is that whenever i want to test it on a simulator or a actual physical device it does nothing. And i cannot find anything online regarding using emulator with a physical device in your local lan.
What could be stopping my physical device to make a connection with my Macbook where the emulators are running?
See my firebase.json config below:
NOTE: i have tryed to put "host": "192.168.x.x" or "0.0.0.0" <- my macbook ip adres
But with no result.
{
"firestore": {
"rules": "firestore.rules",
"indexes": "firestore.indexes.json"
},
"functions": {
"predeploy": [
"npm --prefix \"$RESOURCE_DIR\" run lint"
]
},
"storage": {
"rules": "storage.rules"
},
"emulators": {
"auth": {
"port": 9099
},
"functions": {
"port": 5001
},
"firestore": {
"port": 8080
},
"storage": {
"port": 9199
},
"ui": {
"enabled": true
}
}
}
code below FirebaseApp.configure()
Where Localhost is "192.168.x.x" my macbook IP
let settings = Firestore.firestore().settings
settings.host = "localhost:8080"
settings.isPersistenceEnabled = false
settings.isSSLEnabled = false
Firestore.firestore().settings = settings
In the info.plist i added App transport Security Settings:
Allows local networking = YES
What i see in debug.log (This might be unrelated)
Jul 04, 2021 10:20:53 AM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
INFO: Detected non-HTTP/2 connection.
What could be a problem to stop my phone from connecting to my firebase emulators hosted on my macbook which is in the same local network as my phone.
When i use firebase cloud version everything works fine.
Could it be something in my firewall or on the macbook itself?
Which would explain that both physical and a simulator cannot write /read to firestore.
Hope some one can help me!
Would love to test functions and everything else locally first.
Greetings,
Dylan

First time deploying meteor app with meteor-up

This is the first time i am deploying from Meteor-up and I followed the docs to deploy a dummy application first. I am deploying on a shared linux server. Everything is going great but i can't find my app on ROOT_URL. My domain is pointing to the server and that very domain is also my ROOT_URL. when I hit the domain link it goes to the index of file explorer on the server instead of my web app. I tried to find logs but logs command and --verbose flag returned no log and the command simply run as usual.
Mup version (``1.5.3`):
Mup config
{ "servers": {
"one": {
"host": "1.2.3.4",
"username": "totalti1",
"password": "password",
"opts": {
"port": 2083
}
} }, "proxy": {
"servers": {
"one": {}
},
"domains": "host.com,subdomain.host.com",
"shared": {
"httpPort": 80,
"httpsPort": 443
} }, "app": {
"name": "my-app",
"path": "../.",
"deployCheckWaitTime": 300,
"servers": {
"one": {}
},
"buildOptions": {
"serverOnly": true
},
"env": {
"ROOT_URL": "https://host.com",
"MONGO_URL": "mongodb://mongodb:27017/my-app",
"MONGO_OPLOG_URL": "mongodb://localhost/local",
"VIRTUAL_HOST": "host.com,subdomain.host.com",
"HTTPS_METHOD": "noredirect",
"VIRTUAL_PORT": 3000,
"HTTP_FORWARDED_COUNT": 1
},
"docker": {
"image": "abernix/meteord:node-12-base",
"prepareBundle": false,
"stopAppDuringPrepareBundle": true,
"imagePort": 3000,
"args": [
"--link=mongodb:mongodb"
]
},
"enableUploadProgressBar": true,
"type": "meteor" }, "mongo": {
"version": "3.4.1",
"servers": {
"one": {}
},
"dbName": "DemoApp" } }
the port of my host is 2083 and I am not sure if that is causing a problem. I am not sure if the deployment was unsuccessful or the URL had a mistake. I was able to get some log after setting the debug Environmental variable. And here is it.
Output of command
$ DEBUG=mup* mup reconfig --verbose
mup:updates checking for updates +0ms
mup:updates Packages: [ { name: 'mup', path: '/usr/lib/node_modules/mup/package.json' } ] +2ms
mup:updates retrieving tags for mup +2ms
mup:api Running command default.reconfig +0ms
mup:module:default exec => mup reconfig +0ms
mup:api Running command meteor.envconfig +2ms
mup:module:meteor exec => mup meteor envconfig +0ms
Started TaskList: Configuring App [213.136.76.119] - Pushing the Startup Script
mup:updates finished update check for mup +1s
I am looking for some instant help as i am stuck on this deployment for three days now. Thanks in Advance
EDIT
Is there a way to know that the deployment was successful or not. Also is there something wrong with my ROOT_URL? Root url contains the IP of server on which i have hosted the app. The domain also points to the IP. When I access by IP it says
Sorry!
IP changed or server misconfig or site may have moved to different ip. Contact your hosting provider.
When i access via domain it shows the empty directory the default domain is set to.

How do I connect to my local Realtime Database emulator in my Flutter app?

I am using the Realtime Database and Functions for my Flutter app. I've set up local emulators for both Database and Functions, so I can test Functions locally without the deployment cost. Now I want to connect my Flutter app to these local emulators, but I am having some trouble finding out how to do it.
The FlutterFire docs describes how to do this for Firestore (https://firebase.flutter.dev/docs/firestore/usage#emulator-usage), but not for the Realtime Database. Surely there must be a way to connect to the emulators, even though I am using the Realtime Database?
I have tried the following:
String host = Platform.isAndroid ? '10.0.2.2:4000' : 'localhost:4000';
FirebaseDatabase database = FirebaseDatabase(
app: Firebase.app(),
databaseURL: host,
);
But that gives me the error:
Unhandled Exception: PlatformException(error, Invalid Firebase Database url specified: 10.0.2.2:4000, null)
I am using the firebase_core and firebase_database packages on pub.
Digging deeper into Firebase Java SDK, I've found that .useEmulator() only sets host and port for creating the databaseURL and in short is just a refactoring wrapper.
Code below should work with FlutterFire Realtime Database package:
String host = Platform.isAndroid ? 'http://10.0.2.2:9000' : 'http://localhost:9000';
FirebaseDatabase database = FirebaseDatabase(
app: Firebase.app(),
databaseURL: host,
);
Also, do check your firebase.json for the correct port to use. Default should be 9000 for database.
{
"firestore": {
"rules": "firestore.rules",
"indexes": "firestore.indexes.json"
},
"functions": {
"predeploy": [
"npm --prefix \"$RESOURCE_DIR\" run lint",
"npm --prefix \"$RESOURCE_DIR\" run build"
],
"source": "functions"
},
"storage": {
"rules": "storage.rules"
},
"emulators": {
"auth": {
"port": 9099
},
"functions": {
"port": 5001
},
"firestore": {
"port": 8080
},
"database": {
"port": 9000
},
"ui": {
"enabled": true
}
}
}
According to the Firebase documentation for Android, using the Realtime Database emulator requires a call database.useEmulator("10.0.2.2", 9000). A quick search of the FlutterFire code shows no such calls, so it seems that emulator usage isn't implemented in FlutterFire yet.
I also couldn't find an open issue for it, so you might want to file a feature request.
Following code worked for me. Its almost similar to #Florin Stan answer. Just the namespace of the database was missing.
String host = Platform.isAndroid ? 'http://10.0.2.2:9000' : 'http://localhost:9000';
dbInstance= FirebaseDatabase(
databaseURL: '$host?ns=YOUR_DATABASE_NAMESPACE',
);
Database namespace can be found in firebase realtime database emulator UI.

"Unexpected error determining execution environment" when running Firebase emulator

Everything works correctly when I deploy my functions, but running the same code locally with the Firebase emulator gives me the following error:
{
"message": "Unexpected error determining execution environment: request to http://169.254.169.254/computeMetadata/v1/instance failed, reason: connect EHOSTDOWN 169.254.169.254:80 - Local (192.168.1.101:56456)",
"type": "system",
"errno": "EHOSTDOWN",
"code": "EHOSTDOWN",
"config": {
"url": "http://169.254.169.254/computeMetadata/v1/instance",
"headers": {
"Metadata-Flavor": "Google"
},
"retryConfig": {
"noResponseRetries": 0,
"currentRetryAttempt": 0,
"retry": 3,
"retryDelay": 100,
"httpMethodsToRetry": [
"GET",
"HEAD",
"PUT",
"OPTIONS",
"DELETE"
],
"statusCodesToRetry": [
[
100,
199
],
[
429,
429
],
[
500,
599
]
]
},
"responseType": "text",
"timeout": 3000,
"params": {},
"method": "GET"
}
}
What should I do to be able to test my code with the emulator?
If your cloud function requires admin rights, then you need to configure a service account for the cloud functions to run under.
Follow the instructions here:
https://firebase.google.com/docs/admin/setup
The mains steps are:
1) Create a Service Account and download the .json private key files (keep this secret)
In the console where you will run your emulator:
2) Set the GOOGLE_APPLICATION_CREDENTIALS environment variable to the absolute path of the private key file saved in step 1. For example export GOOGLE_APPLICATION_CREDENTIALS="/Users/..../...account.json"
3) Now run your emulator firebase emulators:start --only functions
Now the locally emulated function knows the environment. So when you do something like admin.initializeApp(functions.config().firebase); it gets configured properly.

Resources