I've configured firebase ab-testing. Everything works fine except there is no impact user on console.
Actually, I can see UI and log show ab-testing is applied.
Moreover, by checking the other StackoverFlow topic, activateFetched also invoked after fetch successfully.
Moreover, I've referenced
Firebase Remote Config A/B testing shows no results after 24 hours
Firebase Remote Config results on initial request
Remote Config A/B Test does not provide results on iOS
But those are no work on my case.
Is there anything miss or any other need to check so that client can response AB testing result to firebase console.
Thanks for your help first.
Code snippet:
[FIRApp configure];
FIRRemoteConfigSettings* configSettings = [[remoteConfig configSettings] initWithDeveloperModeEnabled:YES];
[[FIRRemoteConfig remoteConfig] setConfigSettings:configSettings];
[[FIRRemoteConfig remoteConfig] fetchWithExpirationDuration:duration completionHandler:^(FIRRemoteConfigFetchStatus status, NSError *error) {
if (status == FIRRemoteConfigFetchStatusSuccess) {
BOOL configFound = [[FIRRemoteConfig remoteConfig] activateFetched];
A couple things to check or take note of:
Make sure you're using and have deployed the latest Remote Config SDK. Earlier versions don't work with A/B test experiments.
Be sure to verify your experiment on a test device by following the documentation here
It can take a couple days for data to come in for your experiment.
Please call the functions in the following order:
fetch()
Call activatefetched() in the completion handler of fetch().
Fire activation event. If you need to call activation event immediately after activatefetched(), add a time delay of a few seconds. This is because activatefetched() process asynchronously and hence the function may not execute completely, before the activation event is fired.
Once done, test a running experiment on test device. In the debug logs search with string "exp_X" where 'X' is the experiment Id. You will find the experiment Id in the URL of the experiment. If you find the experiment ID in the debug logs while executing the code on test device, it means the device was covered in experiment.
Also if the experiment setup is correct, the running experiment will show 1 active experiment user in the console.
Related
I need to actively receive crash notifications for firebase functions.
Is there any way to set up Slack webhooks to receive a message when Firebase Functions throw an Error, functions crash, or something like that?
I would love to receive issue messages by velocity ie: Firebase Functions crash 50 times a day.
Thank you so much.
First you have to create a log based (counter) metric that will be counting specific error occurencies and second - you create alerting policy with Slack notification channel.
Let's start from finding corresponding logs that appear when the function throws an error. Since I didn't have one that would crash I used logs that indicated that it was started.
Next you have to create a log based metric. Ignore the next screen and go to Monitoring > Alerting. Click on "Create new policy", find your metric and select "Rolling Window" to whatever time period you need. For testing I used 1 minute. Then set "Rollind windows function" to "mean".
Now configure when the alert has to be triggered - I chose over 3 (within 1 minute window).
On the next screen you select notification channel. In case of Slack it has to be configured first in "Notification Channels".
You can save policy the policy now.
After a few minutes I gathered enough data to generate two incidents:
And here's some alerting related documentation that may help you understand how to use them.
I have a Firebase Function that subscribes to a Cloud PubSub topic. App is initialized very simply like this:
import * as admin from 'firebase-admin';
admin.initializeApp();
I'm getting this error:
"Error: Could not load the default credentials. Browse to https://cloud.google.com/docs/authentication/getting-started for more information.
at GoogleAuth.getApplicationDefaultAsync (/srv/functions/node_modules/google-auth-library/build/src/auth/googleauth.js:161:19)
at process._tickCallback (internal/process/next_tick.js:68:7)"
Here's the weird thing. It typically works. In other words, if I trigger it a second time it works. And a third time. Most often it seems to fail the first time it runs after a new firebase deploy and possibly on a "cold start."
Not sure what I'm doing wrong and why it would fail only on the first run.
SOLVED! This answer helped:
Error: Could not load the default credentials (Firebase function to firestore)
From within a Firebase Function for an API call, I was publishing to a Cloud PubSub topic like this:
pubsub.topic(topicName).publish(dataBuffer, customAttributes)
I was not awaiting the response and was immediately sending the 2XX HTTP response back to the client. The execution seemed to continue fine, but obviously it did not behave as intended.
Sometimes the API response call itself would fail (and never publish the message), but sometimes not. In other cases, the publish would succeed but the Firebase Function subscribing to the topic would fail!
In all cases, this seemed to resolve itself after running the script a second time. For this reason, I still believe it had something to do with a cold start.
But since I changed it to await like this:
await pubsub.topic(topicName).publish(dataBuffer, customAttributes)
I have not seen this problem happen again.
I created a serverless function that performs that Firebase Token Validation.
Everything works as intended. Except, I have I get errors on subsequent calls to initialize my app that the default app already exists (same container). This raises some questions.
If my serverless infrastructure was to spin up multiple concurrent containers, each working to initialize the app. Would this also cause this error? That the app is initiailized elsewhere? Or is this error isolated to local instances?
If its the latter, If I provide a named app based on the container it is spun up in, is there a firebase limit to the maximum number of apps that can be initialized at once?
This is how I am initializing the app now:
cred = credentials.Certificate(SERVICE)
firebase_admin.initialize_app(cred)
I could do this but am not sure about firebase app limits or concurrent initializations (cant find any specifics in docs):
cred = credentials.Certificate(SERVICE)
firebase_admin.initialize_app(cred, 'APP-NAME-[CONTAINERID]')
Or, should I just re-write this using my own JWT Decoder and grabbing the public keys from google?
And here is the full error:
Error occurred setting firebase credentials: The default Firebase app already exists. This means you called initialize_app() more than once without providing an app name as the second argument. In most cases you only need to call initialize_app() once. But if you do want to initialize multiple apps, pass a second argument to initialize_app() to give each app a unique name.
UPDATE: AWS Lambda, Python.
I am going to test out with the following, to prevent re-initializing the app within the same container on warm function executions and move forward with the assumption that there are no API limits on performing auth.validate_id_token() and that this won't conflict with concurrent container executions. Ill report back if it tests out differently.
try:
firebase_admin.get_app()
logger.info('firebase already intialized.')
except ValueError as e:
logger.info('firebase not initialized. initialize.')
cred = credentials.Certificate(SERVICE)
firebase_admin.initialize_app(cred)
I will probably still migrate to another JWT validation to reduce function size (since I already have a jwt library for my own app use) and migrate away from relying on Firebase API to decode it.
If you get an error when initializing the admin SDK that says the default app already exists, that just means you're trying to init the admin SDK twice in the same process. Obviously, don't do that. If you init once and only once per process, you will never see this error.
You will have to take some care to only call the init method once per server instance. It's not clear exactly what you're doing from the code you've shown. I don't know about python, but with node, you can init once in a global context without problems. If you need to init during a function execution, you should have some flag to check that ensures the default Firebase app hasn't already been initialized, and init only conditionally based on that flag.
I configured Firebase Remote Config A/B testing for Android, and we did rollout on at least 10K devices.
For some reason, I see "0 users" in my A/B test after more than 24 hours.
Firebase GMS version is: 11.8.0
Should it show A/B participants in real-time or it's ok to see 0 users after 24 hours?
P.S: We are able to get AB test variants on test devices through Firebase Instance Id, it works well.
The simplest experiment which is running has only app package as a target, with no additional filters. And it shows 0 users as well.
Finally, we found an answer!
Maybe somebody will find it helpful:
For now, it happens (no data in Firebase remote config A/B test experiment) if you have an activation event configured for A/B test experiment.
If you have 2 different experiments, both will fail to get results even if you have "activation event" configured only in 1 of them.
Additionally, remote config will not work as well, you'll be able to get only default values.
We already reported to Google about, so they'll fix it at some point I hope.
Another useful info which is really hard to get:
How long is it ok to see "0 Total Users" in experiment I've just
started?
It takes many hours before you can see any data in your experiment. We were able to see results only after 21 hours after experiment start, so if you configured everything well, don't worry and wait for at least 24 hours. It will show 0 "Total Users" for many hours after the start.
Should I use app versionName or versionCode in "Version" field of
experiment setup?
You should use versionName.
Some useful info from support:
Firebase SDK
Make sure your users have the version of your app with the latest SDK.
Since your experiment is with Remote Config
When activateFetched() is called, all events from that point on will be tagged with the experiment. If you have a goal or activation event that happens before activateFetched(), such as automatic events like first_open, session_start, etc., the experiment setup might be wrong.
Are you using an Activation Event?
Make sure to call fetch() and activateFetched() before the activation event occurs.
Experiment ID of the experiments (if support asks you about)
It's the number at the end of the URL while viewing experiment results.
This debugging log could be useful to get what is going on
Also:
The good way to check if your experiment is working now is to set it to a specific version you didn't publish yet and check logs from remote config with the fresh app install(or erase all app data & restart).
It should show different variant every time you reinstall the app, since your Firebase Instance ID changes after app reinstall/app data erase.
If you see variants change - then A/B test is running well.
In your "build.graddle": don't forget to set the same versionName which you set in experiment setup.
In my case, I was receiving results of A/B testing but suddenly, it stopped to appear. It had continued for 7 days and then results appeared. Firebase Support manager said:
what I suspected here is just a delay in showing the result in the
experiments
Additionally, she said that
With that, I would suggest always using the latest SDK version and
enabling Google Analytics data sharing.
In my case, I used I wasn't using the latest SDK version, but Google Analytics was enabled for "Benchmarking", "Technical Support", "Account Specialists" except for "Google products & services". I believe these settings were enabled by default (the screenshot from Google Analytics):
Bug:
I'm consistently getting error code -1009 "The Internet connection appears to be offline." errors when making URLSession requests in an Apple Watch extension on an Apple Watch Series 3 when connected to the Internet only via LTE.
Steps to Reproduce:
Install the app.
Configure your device so that it's only on LTE.
Verify your connection to LTE using iMessages, e.g.
Launch the app.
Initialize a URLSession using the .default or .ephemeral session configuration.
Make a data task request for any known-good https URL.
Expected Behavior:
The request manages to reach the destination.
Observed Behavior:
The request fails immediately with error code -1009 "The Internet connection appears to be offline."
Code Sample:
let config = URLSessionConfiguration.ephemeral
let sesh = URLSession(configuration: config)
let url = URL(string: "https://google.com")!
sesh.dataTask(with: request) { (_, _, error) in
print(error)
}.resume()
NOPE: SEE UPDATE #3 BELOW: The crucial missing element: you must set the waitsForConnectivity flag on your session configuration to true.
let config = URLSessionConfiguration.ephemeral
config.waitsForConnectivity = true
let sesh = URLSession(configuration: config)
let url = URL(string: "https://google.com")!
sesh.dataTask(with: request) { (_, _, error) in
print(error)
}.resume()
If you do not set that flag, the requests fail immediately because LTE access isn't available instantly but only after the briefest of delays. Setting this flag to true makes the requests work. In my testing there even seems to be no appreciable difference in timing between enabling the waitsForConnectivity over LTE and making the same request without enabling waitsForConnectivity but conducted over WiFi, almost like the waiting period enabled by waitsForConnectivity in some scenarios is a next-turn-of-the-runloop kind of situation.
Update #1
I am unable to make any requests over LTE. When waitsForConnectivity is set to true, the requests just timeout according to the timeout properties of the session config. When waitsForConnectivity is false, the requests fail immediately. I'll update my question and answer when I have more information. I'm waiting on a response from an Apple TSI request which usually takes several days.
Update #2
Adding to the mystery, the same sample code runs fine over cellular on two other developers' hardware. I know that my hardware is good because Apple's apps fun fine over LTE on it (phone calls rolling down the highway with nothing but my watch in the car). So there's something really fishy going on. I've asked Apple DTS to look into this, and they can't reproduce the issue either. I'll be following up with them as soon as I can.
Update #3
Sometime in the intervening weeks after I last updated this post, cellular requests started working in my apps. I didn't change anything about my watch, no software updates, no resets, nothing. I didn't even recompile the code; the same build is still on my watch as previously. It just started working as expected, same as it did on other developers' devices.
The only thing strange I noticed is that I got three, back-to-back, identical SMS messages from AT&T notifying me that my Apple Watch is now linked to my iPhone number. Which is strange, because that linkage supposedly occurred the night I unboxed my phone, not two months later. I have no idea if this is related to my issue. All I know is that cellular requests are now working.
I had the same problem but was developing an App for the iPhone. This is what finally solved the problem. I set the configuration objects property:
config.allowsCellularAccess = true
This is very confusing, because the Apple documentation states that this property is set to true by default... but in my case it was not. Also, even though I am using "background tasks," and they are always meant to wait for connectivity, I also set waitsForConnectivity = true, too, just in case.
Just in case someone runs into this error but has everything set up correctly. I was running my project from xCode onto a real device but couldn't get past the internet connectivity issue.
In the code there was a check for __DEV__ to determine what API url to use.
I was building this for running not testing so i assumed it would make __DEV__ false. but it did not, so I had to change the code for that check and set it to a non-localized api url.
even if you are injecting your url, it might not grab the correct one based on if it thinks it is a DEV build or not.