Firebase - Analytics: User engagement graph not showing screen_view events - firebase

I have an app connected to FirebaseAnalytics. I can see that I am sending the screen_view event, and that it is arriving (as is the user_engagement event); but this isn't resulting in the scores appearing in the userEngagement dashboard.
Is there another property that has to be set for the dashboard to show user engagement?
As the events are arriving at Firebase I'm not sure it's relevant but just for completeness I am using #capacitor-community/firebase-analytics on iOS. This is reporting success in the console.
2020-11-07 16:32:28.016270+0000 Development[4563:1132540] 6.34.0 - [Firebase/Analytics][I-ACS023105] Event is not subject to real-time event count daily limit. Marking an event as real-time. Event name, parameters: screen_view (_vs), {
ga_debug (_dbg) = 1;
ga_event_origin (_o) = app;
ga_previous_class (_pc) = /info;
ga_previous_id (_pi) = -3144803485867826237;
ga_previous_screen (_pn) = /info;
ga_realtime (_r) = 1;
ga_screen (_sn) = /welcome;
ga_screen_class (_sc) = /welcome;
ga_screen_id (_si) = -3144803485867826236;
}
2020-11-07 16:32:28.038535+0000 Development[4563:1132540] 6.34.0 - [Firebase/Analytics][I-ACS023087] User property set. Name, value: lifetime_user_engagement (_lte), 6215573
2020-11-07 16:32:28.038767+0000 Development[4563:1132540] 6.34.0 - [Firebase/Analytics][I-ACS023087] User property set. Name, value: session_user_engagement (_se), 703736
2020-11-07 16:32:28.042258+0000 Development[4563:1132793] 6.34.0 - [Firebase/Analytics][I-ACS012018] Saving bundle. size (bytes): 532
2020-11-07 16:32:28.042885+0000 Development[4563:1132793] 6.34.0 - [Firebase/Analytics][I-ACS023116] Bundle added to the upload queue. BundleID, timestamp (ms): 102, 1604766746929
2020-11-07 16:32:28.048243+0000 Development[4563:1132793] 6.34.0 - [Firebase/Analytics][I-ACS023039] Measurement data sent to network. Timestamp (ms), data: 1604766748047, <APMPBMeasurementBatch: 0x2808f90c0>
2020-11-07 16:32:28.052526+0000 Development[4563:1132540] 6.34.0 - [Firebase/Analytics][I-ACS900000] Uploading data. Host: https://app-measurement.com/a
2020-11-07 16:32:28.116422+0000 Development[4563:1132793] 6.34.0 - [Firebase/Analytics][I-ACS901006] Received SSL challenge for host. Host: https://app-measurement.com/a
2020-11-07 16:32:28.168702+0000 Development[4563:1132948] 6.34.0 - [Firebase/Analytics][I-ACS023044] Successful upload. Got network response. Code, size: 204, -1
2020-11-07 16:32:28.173503+0000 Development[4563:1132948] 6.34.0 - [Firebase/Analytics][I-ACS002002] Measurement timer scheduled to fire in approx. (s): -0.2433141469955444
2020-11-07 16:32:28.180798+0000 Development[4563:1132948] 6.34.0 - [Firebase/Analytics][I-ACS002003] Measurement timer canceled

I also agree with Martin, Firebase analytics updates data for 24h, this is actual for collecting data in a/b tests

For anybody else who ends up spending hours debugging this - it's just a processing delay... in the morning (24hours later) the engagement graph has updated.
Do not adjust your screens ;)

Related

Migration from UA to GA4. Not able to receive event on GA4 dashboard

I have a existing UA dashboard with property ID (say UA-ABC). Now created a GA4 dashboard and have a measurement ID ( say GA-XYZ ). I was using a below python script to send the data to UA dashboard. Now replaced the UA tracking ID in the script with GA4 measurement ID. Not able to receive the events in the GA4 dashboard.
import requests
MEASUREMENT_ID = 'G-XYZ'
CLIENT_ID = '555'
EVENT_CATEGORY = 'video'
EVENT_ACTION = 'play'
EVENT_LABEL = 'holiday'
payload = {
'v': '1',
'tid': MEASUREMENT_ID,
'cid': CLIENT_ID,
't': 'event',
'ec': EVENT_CATEGORY,
'ea': EVENT_ACTION,
'el': EVENT_LABEL,
}
response = requests.post('https://www.google-analytics.com/collect', data=payload)
if response.status_code == 200:
print('Event successfully sent to Google Analytics')
else:
print('There was an error sending the event to Google Analytics')
Note: The events are going to the UA dashoard if I use UA tracking in the script.
You appear to be using the
Measurement Protocol (Universal Analytics)
which is designed to send hits to a universal analytics account.
Endpoint
POST /collect HTTP/1.1
Host: www.google-analytics.com
payload_data
If you want to send hits to a GA4 account then you need to use Measurement Protocol (Google Analytics 4)
The endpoint is also diffrent
POST /mp/collect HTTP/1.1
HOST: www.google-analytics.com
Content-Type: application/json
<payload_data>
Remember ga4 is not the same as UA your going to have to redesign your hits and convert them to events.
Event Payload example
{
"client_id": "x",
"events": [
{
"name": "offline_purchase",
"params": {
"engagement_time_msec": "100",
"session_id": "123"
}
}
]
}
That and the measurement protocol for ga4 is extremally limited. You will probably not be able to send all the hits you want to most of them are locked down for use by googles internal sdk's. Have a look at the event-builder you will be able to see what you can send.

Business Object Repository initialized on wrong domain

We are using Intershop 7.10.10.1 and there is strange problem we are facing regarding initialization of PostpaidPriceBORepositoryExtensionImpl (AbstractDomainRepositoryBOExtension). There are 4 application servers, and now and then method "getDomain()" from "AbstractDomainRepositoryBOExtension" just on one application server (and that problem occurs only on that app server until it's restarted) returns different domain (from another channel).
We ere initializing that repository from custom basket PLI extension (BasketPliBOA1CustomExtensionImpl) by:
final BusinessObjectRepositoryContext context = getContext().getVariable(BusinessObjectRepositoryContext.CURRENT);
postpaidPriceBORepository = context.getRepository(PostpaidPriceBORepositoryExtensionFactory.EXTENSION_ID);
This is log message with wrong domain:
[2019-08-22 16:55:19.082 CEST+0200] DEBUG lvpislive1.vipnet.hr ES1 appserver0 [A1-Shop-Site] hr.a1.component.postpaid.price.capi.PostpaidPriceBORepository [] [Storefront] [U4orJF6aQTkzJQPE-Zecvq2QBdF3vzutXXB9fwIB] [3CZ1Al1erNa3mvMK-0-00] "3CZ1Al1erNa3mvMK-0-00" Calling getPostpaidPriceBO with following parameters: productID - BSsK85q6.1IAAAFpaSPwkTzN, tariffID - Ayl_AAEB068AAAFm2D5_ByXz, contractType - A, contractBinding - 24, domainID - VcwK_Slyn1kAAAFl9O1ujvEU.
And here with corect one:
[2019-08-22 16:55:19.145 CEST+0200] DEBUG lvpislive1.vipnet.hr ES1 appserver0 [A1-Shop-Site] hr.a1.component.postpaid.price.capi.PostpaidPriceBORepository [] [Storefront] [U4orJF6aQTkzJQPE-Zecvq2QBdF3vzutXXB9fwIB] [3CZ1Al1erNa3mvMK-0-00] "3CZ1Al1erNa3mvMK-0-00" Calling getPostpaidPriceBO with following parameters: productID - BSsK85q6.1IAAAFpaSPwkTzN, tariffID - Ayl_AAEB068AAAFm2D5_ByXz, contractType - A, contractBinding - 24, domainID - aPIK_Sly.tEAAAFlWeJujvEU.
As you can see on first log message is domain ID from A1-Tomato-Site and strange is that request and log file is for A1-Shop-Site (different channel). Also you can see in log messages that both of them are from same session, even from same request (request ID is 3CZ1Al1erNa3mvMK-0-00).
This is code snippet from PostpaidPriceBORepositoryImpl:
LOGGER.debug("Calling getPostpaidPriceBO with following parameters: productID - {}, tariffID - {}, contractType - {}, contractBinding - {}, domainID - {}.",
productID, tariffID, contractType, contractBinding, getDomain().getDomainID());
final A1PostpaidPricePO postpaidPricePO = postpaidPricePOFactory
.getObjectByAlternateKey(new A1PostpaidPricePOAlternateKey(productID, tariffID, contractType.getName(), contractBinding, getDomain().getDomainID()));
Do you know what could be reason for that? Just to repeat what is strange, this is happening on only one application server (after every restart on different one, so that isn't consistent either). There is possibility if we have luck that after restart this doesn't happen on any of app servers, but after next restart problem occurs on one app server (one time we had problem on two of them from 4).
Thank you for your help.

How to properly connect to FCM?

I wrote the code as it is in the Firebase tutorial page and upon app start it seem to connect without any problem, I get the message:
2016-10-15 19:27:16.945596 engTrain iOS[910:444452] Connected to FCM.
and I receive both messages when app in the fron and notifications when app is in the background.
But when I test a In App Purchase(I'm in debug yet) I get
2016-10-15 19:36:38.356075 engTrain iOS[910:444452] Unable to connect to FCM. Error Domain=com.google.fcm Code=2001 "(null)"
The analytics debug is logging the following data about an _iap event but I can't see any event with this name in my console.
**2016-10-15 19:38:58.825 engTrain iOS[910:] <FIRAnalytics/DEBUG> Event is not subject to real-time event count daily limit. Marking an event as real-time. Event name, parameters: _iap, {
"_c" = 1;
"_dbg" = 1;
"_o" = auto;
"_r" = 1;
currency = JPY;
price = 600000000;
"product_id" = "pro_user";
"product_name" = Pro;
quantity = 1;
value = 600000000;
}**
Has anybody experienced something similar? Is this normal in debug or should I fix something before production.
Thank you.

Symfony2 Authorize.net SIM error

I want to use Authorize.net SIM payment method in Symfony using payum.org.
There is no official gateway for it but there is one in omnipay: omnipay-authorizenet. There is also omnipay-bridge in payum so it is possible to use omnipay gateways in payum.
So I use this setup and after submitting the authorize.net form I get the error:
[date] request.CRITICAL: Uncaught PHP Exception Omnipay\Common\Exception\InvalidRequestException: "Incorrect hash" at .../authorize/vendor/omnipay/authorizenet/src/Message/SIMCompleteAuthorizeRequest.php line 42 {"exception":"[object] (Omnipay\\Common\\Exception\\InvalidRequestException(code: 0): Incorrect hash at .../authorize/vendor/omnipay/authorizenet/src/Message/SIMCompleteAuthorizeRequest.php:42)"} []
BUT this is NOT because of the generated hashes being incorrect - it is because capture url is called second time without the POST data.
On a clean installation of Symfony2 with 3 packages:
composer.json:
"payum/payum-bundle": "0.15.*",
"omnipay/authorizenet": "~2.0",
"payum/omnipay-bridge": "*#stable"
config.yml:
payum:
security:
token_storage:
AppBundle\Entity\PaymentToken: { doctrine: orm }
storages:
AppBundle\Entity\Payment: { doctrine: orm }
gateways:
authorizeGateway:
omnipay_offsite:
type: AuthorizeNet_SIM
options:
hashSecret: 'Simon'
ApiLoginId: 'xxx'
transactionkey: 'xxx'
testMode: false
developerMode: true
Controller:
/**
* #Route("/prepare", name="prepare")
*/
public function prepareAction()
{
$gatewayName = 'authorizeGateway';
$storage = $this->get('payum')->getStorage('AppBundle\Entity\Payment');
$payment = $storage->create();
$payment->setNumber(uniqid());
$payment->setCurrencyCode('USD');
$payment->setTotalAmount(1);
$payment->setDescription('A description');
$payment->setClientId('anId');
$payment->setClientEmail('foo#example.com');
$storage->update($payment);
$captureToken = $this->get('payum.security.token_factory')->createCaptureToken(
$gatewayName,
$payment,
'done' // the route to redirect after capture
);
return $this->redirect($captureToken->getTargetUrl());
}
/**
* #Route("/done", name="done")
*/
public function doneAction(Request $request)
{
...
}
Going to /prepare shows a redirecting to authorize.net page for a second and I'm redirected to external test.authorize.net/gateway/transact.dll (on https) page where I specify card number (test card number) and expiration date in the future.
Submitting this form gives:
An error occurred while trying to report this transaction to the merchant. An e-mail has been sent to the merchant informing them of the error. The following is the result of the attempt to charge your credit card.
This transaction has been approved.
It is advisable for you to contact the merchant to verify that you will receive the product or service.
I'm getting the email about Merchant Email Receipt and the one about the error:
Authorize.Net Developer Center Merchant,
Your script timed out while we were trying to post transaction results to it.
Transaction ID: XXX
Transaction Result: This transaction has been approved.
The transaction is processed correctly, the capture script is called, hashes match and then the capture is called again without post data - then hashes don't match and authorize displays error.
Requests that are made from symfony profiler:
Token IP Method URL Time Status
fe39ec 198.241.162.104 GET .../payment/capture/vVgoUCPtgCOglv6rLwhIbUp64RZ_oIql1_KDpWjdrdk Tue, 17 Nov 2015 09:47:36 +0100 500
bba47c 198.241.162.104 GET .../payment/capture/vVgoUCPtgCOglv6rLwhIbUp64RZ_oIql1_KDpWjdrdk Tue, 17 Nov 2015 09:47:36 +0100 200
c95b83 198.241.162.104 POST .../payment/capture/vVgoUCPtgCOglv6rLwhIbUp64RZ_oIql1_KDpWjdrdk Tue, 17 Nov 2015 09:47:36 +0100 302
a87347 myip GET .../payment/capture/vVgoUCPtgCOglv6rLwhIbUp64RZ_oIql1_KDpWjdrdk Tue, 17 Nov 2015 09:47:30 +0100 200
c95d57 myip GET .../prepare Tue, 17 Nov 2015 09:47:29 +0100 302
From what i see when we call /prepare we get redirected to capture right away this goes to authorize's form. Then after a few seconds (when credit card data is filled in and submitted) authorize (different ip) makes post request to capture. This is 302 redirect (and probably should be a SIM response with javascript code to go back to our page?). Capture is called secod time with GET and calculated hashes don't match - this is 500 response - authorize stays on their url and shows the error message. Done script is never called.
What can be the issue? It's difficult to debug this further because there is payum, omnipay-bridge, omnipay, authorize combined.
Im testing this on the environment accessible from the internet with account on http://developer.authorize.net/ with test mode off.
UPDATE:
If I add notify token to the controller, like this:
/**
* #Route("/prepare", name="prepare")
*/
public function prepareAction()
{
$gatewayName = 'authorizeGateway';
$storage = $this->get('payum')->getStorage('AppBundle\Entity\Payment');
$payment = $storage->create();
$payment->setNumber(uniqid());
$payment->setCurrencyCode('USD');
$payment->setTotalAmount(1); // 1.23 EUR
$payment->setDescription('A description');
$payment->setClientId('anId');
$payment->setClientEmail('foo#example.com');
$storage->update($payment);
$captureToken = $this->get('payum.security.token_factory')->createCaptureToken(
$gatewayName,
$payment,
'done' // the route to redirect after capture
);
$tokenFactory = $this->get('payum.security.token_factory');
$notifyToken = $tokenFactory->createNotifyToken($gatewayName, $payment);
$payment->setDetails(['notifyUrl' => $notifyToken->getTargetUrl()]);
$storage->update($payment);
return $this->redirect($captureToken->getTargetUrl());
}
I get error "Request Notify{model: ArrayObject} is not supported.":
[2015-11-17 17:46:50] request.INFO: Matched route "payum_notify_do". {"route_parameters":{"_controller":"Payum\\Bundle\\PayumBundle\\Controller\\NotifyController::doAction","payum_token":"Lv5ovrC-8vikIB9ItDVLcNfuRzjjaD_pPiE3-6VIV8Y","_route":"payum_notify_do"},"request_uri":".../payment/notify/Lv5ovrC-8vikIB9ItDVLcNfuRzjjaD_pPiE3-6VIV8Y"} []
[2015-11-17 17:46:50] security.INFO: Populated the TokenStorage with an anonymous Token. [] []
[2015-11-17 17:46:50] request.CRITICAL: Uncaught PHP Exception Payum\Core\Exception\RequestNotSupportedException: "Request Notify{model: ArrayObject} is not supported." at .../authorize/vendor/payum/core/Payum/Core/Exception/RequestNotSupportedException.php line 29 {"exception":"[object] (Payum\\Core\\Exception\\RequestNotSupportedException(code: 0): Request Notify{model: ArrayObject} is not supported. at .../authorize/vendor/payum/core/Payum/Core/Exception/RequestNotSupportedException.php:29)"} []
Omnipay bridge 0.15.x does not set a notifyUrl, and the omnipay gateway uses return url as notify one. When notification comes (before you are redirected) the capture token is invalidated and no longer available.
There are two solutions:
Upgrade to 1.0 where notifyUrl is generated. Btw you can use omnipay gateway factory instead of omnipay_offsite.
or you have to generate notify url yourself, and set it to notifyUrl
$tokenFactory = $this->get('payum.security.token_factory');
$notifyToken = $tokenFactory->createNotifyToken($gatewayName, $payment);
$payment->setDetails(['notifyUrl' => $notifyToken->getTargetUrl()]);
$storage->update($payment);

Why Firebase's getAuth() returns an object with past expiry

Is that possible that getAuth() will return an object with expires in the past?
I was under impression that if expires is in the past, getAuth() will return null. But, it looks like I'm wrong.
Here is how I proved I'm wrong:
var resolve = {
auth: function($q) {
var defer = $q.defer();
var authData = rootRef.getAuth();
if (authData === null) {
...
} else {
var now = new Date() / 1000;
console.log('Authenticated!');
console.log(' Auth expiry: ' + authData.expires);
console.log(' Now: ' + now);
console.log('Is expiry in the past? ' + (authData.expires < now ? 'YES' : 'NO'));
defer.resolve();
}
return defer.promise;
}
};
and here is the output:
Authenticated!
Auth expiry: 1415276774
Now: 1415276804.45
Is expiry in the past? YES
If I refresh the page after getting the above output, getAuth() returns null as expected.
To reproduce the issue I do:
Login using email and password
Close the app (browser's tab) before the login session expires (I experimented with 1 minute sessions, but same happens with other lengths sessions)
Wait until the login session expires
Open the app (at this point the code above runs and produces the output above)
Any ideas?
As Chris mentioned in his comment, this appears to be due to differences between client and server times. The expires time specified in the authentication payload is generated by the server using the server's time, but this is likely to be at least slightly different than the one of your client. The important thing to remember is that the client is indeed expired using the TTL you specified, enforced by the server.
I created a simple example to invoke getAuth() every second, and log the difference between the expiration time and current local time upon each request. When tested across multiple iterations, each one looked as follows:
...
session time remaining: 2.23s
session time remaining: 1.23s
session time remaining: 0.23s
session time remaining: -0.76s
session time remaining: -1.77s
session expired
session expired
session expired
...
In short, the client is immediately notified by the server once the session has expired, but the client's timestamp is a few seconds different, which is why the expiration returned from getAuth() may appear to be in the past.

Resources