capacitor-community/firebase-analytics

Ecommerce Items NSNumber Parameters Error For Ios

yunusfillik opened this issue ยท 13 comments

Hi, i want to measure ecommerce events.

You can see documentation for GA4 ecommerce event parameters for analytics with this link.
https://developers.google.com/analytics/devguides/collection/ga4/ecommerce

Firstly; android and web plugins works perfect.
But ios plugun has some issues.

If you send this ecommerce events with ios application;

  • view_item_list
  • view_item
  • select_item
  • add_to_cart
  • purchase
  • etc.
    quantity parameter(in the items) every time "0".

You can see my debug screenshots.

XCODE terminal screenshot;
image

Google anlytics debug view screenshot;
image

Hi, any suggestion how can i fix this issue quickly.

Hello @yunusfillik, can you show the code where you are calling logEvent? It may also be helpful to see your Podfile and Podfile.lock.

Hello @brownoxford, thank you for your interest.

TypeScript
import { Plugins } from '@capacitor/core';
const { FirebaseAnalytics, Device } = Plugins;

postAddToBasket(post: PostDetailDTO) {
    let items = [{
      item_id: post.PostId.toString(),
      item_name: post.PostHeader?.substr(0, 90),
      quantity: 1,
      price: post.SalePrice,
      currency: 'TRY'
    }];
    let param = {
      items: items,
      currency: 'TRY',
      value: post.SalePrice
     };
    FirebaseAnalytics.logEvent({
      name: 'add_to_cart',
      params: param
    });
  }
PodFile
platform :ios, '11.0'
use_frameworks!
# workaround to avoid Xcode caching of Pods that requires
# Product -> Clean Build Folder after new Cordova plugins installed
# Requires CocoaPods 1.6 or newer
install! 'cocoapods', :disable_input_output_paths => true
def capacitor_pods
  # Automatic Capacitor Pod dependencies, do not delete
  pod 'Capacitor', :path => '../../node_modules/@capacitor/ios'
  pod 'CapacitorCordova', :path => '../../node_modules/@capacitor/ios'
  pod 'CapacitorCommunityAppleSignIn', :path => '../../node_modules/@capacitor-community/apple-sign-in'
  pod 'CapacitorCommunityFacebookLogin', :path => '../../node_modules/@capacitor-community/facebook-login'
  pod 'CapacitorCommunityFirebaseAnalytics', :path => '../../node_modules/@capacitor-community/firebase-analytics'
  pod 'CodetrixStudioCapacitorGoogleAuth', :path => '../../node_modules/@codetrix-studio/capacitor-google-auth'
  pod 'CordovaPlugins', :path => '../capacitor-cordova-ios-plugins'
  # Do not delete
end
target 'App' do
  capacitor_pods
  # Add your Pods here
  pod 'Firebase/Messaging'
  pod 'GoogleSignIn'
end
PodFile.lock
PODS:
  - AppAuth (1.4.0):
    - AppAuth/Core (= 1.4.0)
    - AppAuth/ExternalUserAgent (= 1.4.0)
  - AppAuth/Core (1.4.0)
  - AppAuth/ExternalUserAgent (1.4.0)
  - Capacitor (2.4.7):
    - CapacitorCordova
  - CapacitorCommunityAppleSignIn (0.0.1):
    - Capacitor
  - CapacitorCommunityFacebookLogin (1.1.0):
    - Capacitor
    - FBSDKCoreKit (= 9.0.1)
    - FBSDKLoginKit (= 9.0.1)
  - CapacitorCommunityFirebaseAnalytics (0.2.0):
    - Capacitor
    - Firebase
    - Firebase/Analytics
    - Firebase/Core
  - CapacitorCordova (2.4.7)
  - CodetrixStudioCapacitorGoogleAuth (0.0.1):
    - Capacitor
    - GoogleSignIn (~> 5.0.2)
  - CordovaPlugins (2.4.7):
    - CapacitorCordova
  - FBSDKCoreKit (9.0.1):
    - FBSDKCoreKit/Basics (= 9.0.1)
    - FBSDKCoreKit/Core (= 9.0.1)
  - FBSDKCoreKit/Basics (9.0.1)
  - FBSDKCoreKit/Core (9.0.1):
    - FBSDKCoreKit/Basics
  - FBSDKLoginKit (9.0.1):
    - FBSDKLoginKit/Login (= 9.0.1)
  - FBSDKLoginKit/Login (9.0.1):
    - FBSDKCoreKit (~> 9.0.1)
  - Firebase (7.7.0):
    - Firebase/Core (= 7.7.0)
  - Firebase/Analytics (7.7.0):
    - Firebase/Core
  - Firebase/Core (7.7.0):
    - Firebase/CoreOnly
    - FirebaseAnalytics (= 7.7.0)
  - Firebase/CoreOnly (7.7.0):
    - FirebaseCore (= 7.7.0)
  - Firebase/Messaging (7.7.0):
    - Firebase/CoreOnly
    - FirebaseMessaging (~> 7.7.0)
  - FirebaseAnalytics (7.7.0):
    - FirebaseCore (~> 7.0)
    - FirebaseInstallations (~> 7.0)
    - GoogleAppMeasurement (= 7.7.0)
    - GoogleUtilities/AppDelegateSwizzler (~> 7.0)
    - GoogleUtilities/MethodSwizzler (~> 7.0)
    - GoogleUtilities/Network (~> 7.0)
    - "GoogleUtilities/NSData+zlib (~> 7.0)"
    - nanopb (~> 2.30907.0)
  - FirebaseCore (7.7.0):
    - FirebaseCoreDiagnostics (~> 7.4)
    - GoogleUtilities/Environment (~> 7.0)
    - GoogleUtilities/Logger (~> 7.0)
  - FirebaseCoreDiagnostics (7.7.0):
    - GoogleDataTransport (~> 8.0)
    - GoogleUtilities/Environment (~> 7.0)
    - GoogleUtilities/Logger (~> 7.0)
    - nanopb (~> 2.30907.0)
  - FirebaseInstallations (7.7.0):
    - FirebaseCore (~> 7.0)
    - GoogleUtilities/Environment (~> 7.0)
    - GoogleUtilities/UserDefaults (~> 7.0)
    - PromisesObjC (~> 1.2)
  - FirebaseInstanceID (7.7.0):
    - FirebaseCore (~> 7.0)
    - FirebaseInstallations (~> 7.0)
    - GoogleUtilities/Environment (~> 7.0)
    - GoogleUtilities/UserDefaults (~> 7.0)
  - FirebaseMessaging (7.7.0):
    - FirebaseCore (~> 7.0)
    - FirebaseInstanceID (~> 7.0)
    - GoogleUtilities/AppDelegateSwizzler (~> 7.0)
    - GoogleUtilities/Environment (~> 7.0)
    - GoogleUtilities/Reachability (~> 7.0)
    - GoogleUtilities/UserDefaults (~> 7.0)
  - GoogleAppMeasurement (7.7.0):
    - GoogleUtilities/AppDelegateSwizzler (~> 7.0)
    - GoogleUtilities/MethodSwizzler (~> 7.0)
    - GoogleUtilities/Network (~> 7.0)
    - "GoogleUtilities/NSData+zlib (~> 7.0)"
    - nanopb (~> 2.30907.0)
  - GoogleDataTransport (8.2.0):
    - nanopb (~> 2.30907.0)
  - GoogleSignIn (5.0.2):
    - AppAuth (~> 1.2)
    - GTMAppAuth (~> 1.0)
    - GTMSessionFetcher/Core (~> 1.1)
  - GoogleUtilities/AppDelegateSwizzler (7.2.2):
    - GoogleUtilities/Environment
    - GoogleUtilities/Logger
    - GoogleUtilities/Network
  - GoogleUtilities/Environment (7.2.2):
    - PromisesObjC (~> 1.2)
  - GoogleUtilities/Logger (7.2.2):
    - GoogleUtilities/Environment
  - GoogleUtilities/MethodSwizzler (7.2.2):
    - GoogleUtilities/Logger
  - GoogleUtilities/Network (7.2.2):
    - GoogleUtilities/Logger
    - "GoogleUtilities/NSData+zlib"
    - GoogleUtilities/Reachability
  - "GoogleUtilities/NSData+zlib (7.2.2)"
  - GoogleUtilities/Reachability (7.2.2):
    - GoogleUtilities/Logger
  - GoogleUtilities/UserDefaults (7.2.2):
    - GoogleUtilities/Logger
  - GTMAppAuth (1.1.0):
    - AppAuth/Core (~> 1.4)
    - GTMSessionFetcher (~> 1.4)
  - GTMSessionFetcher (1.5.0):
    - GTMSessionFetcher/Full (= 1.5.0)
  - GTMSessionFetcher/Core (1.5.0)
  - GTMSessionFetcher/Full (1.5.0):
    - GTMSessionFetcher/Core (= 1.5.0)
  - nanopb (2.30907.0):
    - nanopb/decode (= 2.30907.0)
    - nanopb/encode (= 2.30907.0)
  - nanopb/decode (2.30907.0)
  - nanopb/encode (2.30907.0)
  - PromisesObjC (1.2.12)
DEPENDENCIES:
  - "Capacitor (from `../../node_modules/@capacitor/ios`)"
  - "CapacitorCommunityAppleSignIn (from `../../node_modules/@capacitor-community/apple-sign-in`)"
  - "CapacitorCommunityFacebookLogin (from `../../node_modules/@capacitor-community/facebook-login`)"
  - "CapacitorCommunityFirebaseAnalytics (from `../../node_modules/@capacitor-community/firebase-analytics`)"
  - "CapacitorCordova (from `../../node_modules/@capacitor/ios`)"
  - "CodetrixStudioCapacitorGoogleAuth (from `../../node_modules/@codetrix-studio/capacitor-google-auth`)"
  - CordovaPlugins (from `../capacitor-cordova-ios-plugins`)
  - Firebase/Messaging
  - GoogleSignIn
SPEC REPOS:
  trunk:
    - AppAuth
    - FBSDKCoreKit
    - FBSDKLoginKit
    - Firebase
    - FirebaseAnalytics
    - FirebaseCore
    - FirebaseCoreDiagnostics
    - FirebaseInstallations
    - FirebaseInstanceID
    - FirebaseMessaging
    - GoogleAppMeasurement
    - GoogleDataTransport
    - GoogleSignIn
    - GoogleUtilities
    - GTMAppAuth
    - GTMSessionFetcher
    - nanopb
    - PromisesObjC
EXTERNAL SOURCES:
  Capacitor:
    :path: "../../node_modules/@capacitor/ios"
  CapacitorCommunityAppleSignIn:
    :path: "../../node_modules/@capacitor-community/apple-sign-in"
  CapacitorCommunityFacebookLogin:
    :path: "../../node_modules/@capacitor-community/facebook-login"
  CapacitorCommunityFirebaseAnalytics:
    :path: "../../node_modules/@capacitor-community/firebase-analytics"
  CapacitorCordova:
    :path: "../../node_modules/@capacitor/ios"
  CodetrixStudioCapacitorGoogleAuth:
    :path: "../../node_modules/@codetrix-studio/capacitor-google-auth"
  CordovaPlugins:
    :path: "../capacitor-cordova-ios-plugins"
SPEC CHECKSUMS:
  AppAuth: 31bcec809a638d7bd2f86ea8a52bd45f6e81e7c7
  Capacitor: 4cd7b342d5a15b1f6f333d687358953afd7b2d8b
  CapacitorCommunityAppleSignIn: 939f0af19043b88c5e287cd6805a10a15f5c4778
  CapacitorCommunityFacebookLogin: 1adddf63eb1266c08fde2891e74f1ca50de3bb84
  CapacitorCommunityFirebaseAnalytics: 5892eebaebe77225e31347116ea93de905a587c3
  CapacitorCordova: 2c9d6e28d9d86c4da087fa2c3537c1841954bb12
  CodetrixStudioCapacitorGoogleAuth: 1f77e1b3b5bb828a7fe82dbf1cf4eade7e5a0269
  CordovaPlugins: df707e4c857058923e0502d3e6cc264001562cc5
  FBSDKCoreKit: fada1a6a0076724678993ff05a633848765ff18c
  FBSDKLoginKit: d5ffe6d808897019ccf16feb6f0a7ab260bc5cd6
  Firebase: cd2ab85eec8170dc260186159f21072ecb679ad5
  FirebaseAnalytics: f3f8f75de34fe04141a69bb1c4bd7e24a80178e1
  FirebaseCore: ac35d680a0bf32319a59966a1478e0741536b97b
  FirebaseCoreDiagnostics: 179bf3831213451c8addd036aca7fcf5492ec154
  FirebaseInstallations: 42c86e7b02ff75b7f27f85833bf5dcb5f38a9774
  FirebaseInstanceID: cf940324a20ac14a27ad1e931d15ac9d335526db
  FirebaseMessaging: ce33c2537fdda1d1a4bc82b2245e3c3bf9107684
  GoogleAppMeasurement: 0c3b134b2c0a90c4c24833873894bfe0e42a0384
  GoogleDataTransport: 1024b1a4dfbd7a0e92cb20d7e0a6f1fb66b449a4
  GoogleSignIn: 7137d297ddc022a7e0aa4619c86d72c909fa7213
  GoogleUtilities: 31c5b01f978a70c6cff2afc6272b3f1921614b43
  GTMAppAuth: 197a8dabfea5d665224aa00d17f164fc2248dab9
  GTMSessionFetcher: b3503b20a988c4e20cc189aa798fd18220133f52
  nanopb: 59221d7f958fb711001e6a449489542d92ae113e
  PromisesObjC: 3113f7f76903778cf4a0586bd1ab89329a0b7b97
PODFILE CHECKSUM: d4e5c01f5847611326008a8fa000ebb8a17b5682
COCOAPODS: 1.10.1

Hi @brownoxford, did you find any solution.

I have the exact same issue!

I need to set up a local test to see if I can reproduce - I'll try to do that this week.

Just for fun: You could try to convert it to an string. quantity: "1",
I don't know if it should be like this but the price is also different

I tried string value but it doesn't work :( @markxoe.

I think I figured it out. items cannot be an object or an array, it has to be either an string or int. See here

I'm definitely able to reproduce this problem, and it appears to be happening inside of the FirebaseAnalytics pod binary, so there is not much we can do about it. I tried updating to v7.9.0 but still had the same problem.

While messing around with options and passing items as an object (instead of an array containing an object), I came across an error that indicates that NSArray is allowed here:

2021-04-02 17:53:16.842509-0400 App[85898:28131503] 7.9.0 - [Firebase/Analytics][I-ACS035001] Cannot create Value type with unsupported value. The Value has to be NSNumber, NSString or NSArray (if supported). Value: {
    affiliation = "Google Store";
    coupon = "SUMMER_FUN";
    currency = USD;
    discount = "2.22";
    "item_brand" = Gucci;
    "item_category" = pants;
    "item_id" = "SKU_12345";
    "item_name" = jeggings;
    "item_variant" = black;
    price = "9.99";
    quantity = 1;
}

I also tried various things like:

  • changing quantity to Quantity (resulted in error about using custom parameters)
  • passing quantity value as an explicit string, e.g., quantity: "1" (no change)
  • passing quantity value as a decimal, e.g., quantity: 1.2 (no change)

The only other troubleshooting option I can see is running my own man-in-the-middle proxy to see what's going over the TLS connection, but I don't have time to do that this week and I'm not sure it would help anyway.

I would suggest submitting a bug to the firebase analytics team and/or engaging your support contact at Google if you have one. I was not able to find a place to submit bugs for this since the FirebaseAnalytics pod does not seem to be open sourced.

I'm closing this as out of scope for the project, but if you find anything that indicates otherwise or have other testing suggestions, please let me know.

Actually, I spoke too soon. I'm reopening because dropping the following into logEvent in plugin.swift works:

        // A pair of jeggings
        var jeggings: [String: Any] = [
          AnalyticsParameterItemID: "SKU_123",
          AnalyticsParameterItemName: "jeggings",
          AnalyticsParameterItemCategory: "pants",
          AnalyticsParameterItemVariant: "black",
          AnalyticsParameterItemBrand: "Google",
          AnalyticsParameterPrice: 9.99,
        ]

        // Specify order quantity
        jeggings[AnalyticsParameterQuantity] = 2

        // Prepare item detail params
        var itemDetails: [String: Any] = [
          AnalyticsParameterCurrency: "USD",
          AnalyticsParameterValue: 19.98
        ]

        // Add items
        itemDetails[AnalyticsParameterItems] = [jeggings]

        // Log an event when product is added to cart
        Analytics.logEvent(AnalyticsEventAddToCart, parameters: itemDetails)

Ok, I found the issue and am working on a PR for the fix - FirebaseAnalytics silently converts any quantity value to zero if it is not an integer - this includes integer strings like quantity: '1'. When Capacitor reads in the options passed to plugins, integer values are stored as NSNumeric, from which FirebaseAnalytics is not properly reading an integer value (maybe because this can also store floating point and other numeric types, I don't have access to the source to check).

@brownoxford you are the best. Thank you so much.
How can i buy you a cup of coffee.