qonversion / react-native-sdk

React Native SDK for cross-platform in-app purchase and subscription infrastructure, revenue analytics, engagement automation, and integrations

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

App crashes after updating to 6.2.0

Orange9000 opened this issue · comments

Hello

We started having app crashes in dev mode after updating to 6.2.0 from 4.4.2 (haven't tested release mode yet).
There seems to be some kind of module conflict related to react-native-appmetrica (natively based on YandexMobileMetrica on iOS and com.yandex.android:mobmetricalib on Android. And also patched with additional functionality to support certain native methods). Commenting out certain code blocks in js code prevents crashes. Specifically, on Android these would be AppMetrica.reportEvent and AppMetrica.reportUserProfile, on iOS - AppMetrica.requestAppMetricaDeviceID.

iOS crash stacktrace leads to [YMMYandexMetrica requestAppMetricaDeviceIDWithCompletionQueue:nil completionBlock:completionBlock]; in native code.

Haven't been able to pinpoint the exact stacktrace on android.

Also, no crashes on qonversion 5.0.0.

I tried reverting the upgrade and crashes disappear. Upgraded again, cleaned all the caches and crashes resume. Checked that multiple times and concluded that qonversion could be the main source of an issue.

Hello! Sorry for not getting back to you sooner. We will try to reproduce your issue and will return as soon as we get any results.

This issue is stale because it has been open 7 days with no activity. Remove stale label or comment or this will be closed in 5 days.

Could you please clarify, which version of react-native-appmetrica you use as well as the versions of react-native and Android/iOS?

Also, a minimal reproducible example would be much appreciated and will significantly speed up the investigation.

I am using

@npm_redstart/react-native-appmetrica@2.3.0 which is a fork of an official module, which is also patched by me on a project level. Quite messy, yes.
react-native@0.70.2
Android 12 on a real device
iOS 16.2 on a simulator

The patch:

diff --git a/node_modules/@npm_redstart/react-native-appmetrica/android/build.gradle b/node_modules/@npm_redstart/react-native-appmetrica/android/build.gradle
index 129d8e8..885143a 100644
--- a/node_modules/@npm_redstart/react-native-appmetrica/android/build.gradle
+++ b/node_modules/@npm_redstart/react-native-appmetrica/android/build.gradle
@@ -18,17 +18,17 @@
 //   original location:
 //   - https://github.com/facebook/react-native/blob/0.58-stable/local-cli/templates/HelloWorld/android/app/build.gradle
 
-def DEFAULT_COMPILE_SDK_VERSION = 28
-def DEFAULT_BUILD_TOOLS_VERSION = '28.0.3'
-def DEFAULT_MIN_SDK_VERSION = 16
-def DEFAULT_TARGET_SDK_VERSION = 28
+def DEFAULT_COMPILE_SDK_VERSION = 30
+def DEFAULT_BUILD_TOOLS_VERSION = '30.0.2'
+def DEFAULT_MIN_SDK_VERSION = 21
+def DEFAULT_TARGET_SDK_VERSION = 30
 
 def safeExtGet(prop, fallback) {
     rootProject.ext.has(prop) ? rootProject.ext.get(prop) : fallback
 }
 
 apply plugin: 'com.android.library'
-apply plugin: 'maven'
+apply plugin: 'maven-publish'
 
 buildscript {
     // The Android Gradle plugin is only required when opening the android folder stand-alone.
@@ -47,7 +47,7 @@ buildscript {
 }
 
 apply plugin: 'com.android.library'
-apply plugin: 'maven'
+apply plugin: 'maven-publish'
 
 android {
     compileSdkVersion safeExtGet('compileSdkVersion', DEFAULT_COMPILE_SDK_VERSION)
@@ -81,7 +81,7 @@ repositories {
 dependencies {
     //noinspection GradleDynamicVersion
     implementation 'com.facebook.react:react-native:+'  // From node_modules
-    implementation 'com.yandex.android:mobmetricalib:3.21.1'
+    implementation 'com.yandex.android:mobmetricalib:5.3.0'
     implementation 'com.android.installreferrer:installreferrer:1.1.2'
 }
 
@@ -119,17 +119,18 @@ afterEvaluate { project ->
     task androidJavadoc(type: Javadoc) {
         source = android.sourceSets.main.java.srcDirs
         classpath += files(android.bootClasspath)
-        classpath += files(project.getConfigurations().getByName('compile').asList())
+        project.getConfigurations().getByName('implementation').setCanBeResolved(true)
+        // classpath += files(project.getConfigurations().getByName('implementation').asList())
         include '**/*.java'
     }
 
     task androidJavadocJar(type: Jar, dependsOn: androidJavadoc) {
-        classifier = 'javadoc'
+        archiveClassifier = 'javadoc'
         from androidJavadoc.destinationDir
     }
 
     task androidSourcesJar(type: Jar) {
-        classifier = 'sources'
+        archiveClassifier = 'sources'
         from android.sourceSets.main.java.srcDirs
         include '**/*.java'
     }
@@ -148,12 +149,11 @@ afterEvaluate { project ->
         archives androidJavadocJar
     }
 
-    task installArchives(type: Upload) {
-        configuration = configurations.archives
-        repositories.mavenDeployer {
-            // Deploy to react-native-event-bridge/maven, ready to publish to npm
-            repository url: "file://${projectDir}/../android/maven"
-            configureReactNativePom pom
+    publishing {
+        repositories {
+            maven {
+                url = uri("${rootProject.projectDir}/maven-repo")
+            }
         }
     }
 }
diff --git a/node_modules/@npm_redstart/react-native-appmetrica/android/src/main/java/com/yandex/metrica/plugin/reactnative/AppMetricaModule.java b/node_modules/@npm_redstart/react-native-appmetrica/android/src/main/java/com/yandex/metrica/plugin/reactnative/AppMetricaModule.java
index 6663f8a..ba6b8d0 100644
--- a/node_modules/@npm_redstart/react-native-appmetrica/android/src/main/java/com/yandex/metrica/plugin/reactnative/AppMetricaModule.java
+++ b/node_modules/@npm_redstart/react-native-appmetrica/android/src/main/java/com/yandex/metrica/plugin/reactnative/AppMetricaModule.java
@@ -57,6 +57,18 @@ public class AppMetricaModule extends ReactContextBaseJavaModule {
         }
     }
 
+    @ReactMethod
+    public void enableSessionTracking(Promise promise) {
+        Activity activity = getCurrentActivity();
+        if (activity != null) { // TODO: check
+            YandexMetrica.enableActivityAutoTracking(activity.getApplication());
+            promise.resolve("success session tracking");
+        } else {
+            Log.w(TAG, "Activity is not attached");
+            promise.resolve("failure session tracking");
+        }
+    }
+
     @ReactMethod
     public void getLibraryApiLevel(Promise promise) {
         promise.resolve(YandexMetrica.getLibraryApiLevel());
@@ -79,11 +91,12 @@ public class AppMetricaModule extends ReactContextBaseJavaModule {
 
     @ReactMethod
     public void reportError(String message) {
-        try {
-            Integer.valueOf("00xffWr0ng");
-        } catch (Throwable error) {
-            YandexMetrica.reportError(message, error);
-        }
+        YandexMetrica.reportError(message, message);
+        // try {
+        //     Integer.valueOf("00xffWr0ng");
+        // } catch (Throwable error) {
+        //     YandexMetrica.reportError(message, error);
+        // }
     }
 
     @ReactMethod
@@ -141,7 +154,7 @@ public class AppMetricaModule extends ReactContextBaseJavaModule {
     public void reportUserProfile(@NonNull String userId, @NonNull ReadableMap profile) {
         UserProfile userProfile = Utils.toUserProfile(profile);
 
-        YandexMetrica.setUserProfileID(userId);
+        // YandexMetrica.setUserProfileID(userId);
 
         YandexMetrica.reportUserProfile(userProfile);
     }
diff --git a/node_modules/@npm_redstart/react-native-appmetrica/android/src/main/java/com/yandex/metrica/plugin/reactnative/Utils.java b/node_modules/@npm_redstart/react-native-appmetrica/android/src/main/java/com/yandex/metrica/plugin/reactnative/Utils.java
index 48e7ee2..14eaaaf 100644
--- a/node_modules/@npm_redstart/react-native-appmetrica/android/src/main/java/com/yandex/metrica/plugin/reactnative/Utils.java
+++ b/node_modules/@npm_redstart/react-native-appmetrica/android/src/main/java/com/yandex/metrica/plugin/reactnative/Utils.java
@@ -34,6 +34,10 @@ import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.Iterator;
 import java.util.Map;
+import java.util.Calendar;
+import java.util.Date;
+
+import static com.facebook.react.bridge.ReadableType.Array;
 
 abstract class Utils {
 
@@ -49,9 +53,9 @@ abstract class Utils {
         if (configMap.hasKey("firstActivationAsUpdate")) {
             builder.handleFirstActivationAsUpdate(configMap.getBoolean("firstActivationAsUpdate"));
         }
-        if (configMap.hasKey("installedAppCollecting")) {
-            builder.withInstalledAppCollecting(configMap.getBoolean("installedAppCollecting"));
-        }
+        // if (configMap.hasKey("installedAppCollecting")) {
+        //     builder.withInstalledAppCollecting(configMap.getBoolean("installedAppCollecting"));
+        // }
         if (configMap.hasKey("location")) {
             builder.withLocation(toLocation(configMap.getMap("location")));
         }
@@ -76,6 +80,9 @@ abstract class Utils {
         if (configMap.hasKey("statisticsSending")) {
             builder.withStatisticsSending(configMap.getBoolean("statisticsSending"));
         }
+        if (configMap.hasKey("withSessionsAutoTrackingEnabled")) {
+            builder.withSessionsAutoTrackingEnabled(configMap.getBoolean("withSessionsAutoTrackingEnabled"));
+        }
 
         return builder.build();
     }
@@ -112,33 +119,120 @@ abstract class Utils {
         return location;
     }
 
-    static UserProfile toUserProfile(ReadableMap profile) {
-        UserProfile.Builder builder = UserProfile.newBuilder();
-
-        // Updating predefined attributes.
-        if (profile.hasKey("name")) {
-            builder.apply(Attribute.name().withValue(profile.getString("name")));
-        }
-
-        if (profile.hasKey("gender")) {
-            if (profile.getString("gender").equals("male")) {
-                builder.apply(Attribute.gender().withValue(GenderAttribute.Gender.MALE));
-            }
-
-            if (profile.getString("gender").equals("female")) {
-                builder.apply(Attribute.gender().withValue(GenderAttribute.Gender.FEMALE));
-            }
-        }
-
-        if (profile.hasKey("age")) {
-            builder.apply(Attribute.birthDate().withAge(profile.getInt("age")));
-        }
-
-        if (profile.hasKey("enableNotification")) {
-            builder.apply(Attribute.notificationsEnabled().withValue(profile.getBoolean("enableNotification")));
-        }
-
-        return builder.build();
+    static UserProfile toUserProfile(ReadableMap params) {
+      UserProfile.Builder userProfileBuilder = UserProfile.newBuilder();
+      ReadableMapKeySetIterator iterator = params.keySetIterator();
+
+      while (iterator.hasNextKey()) {
+          String key = iterator.nextKey();
+
+          switch (key) {
+              // predefined attributes
+              case "name":
+                  userProfileBuilder.apply(
+                    params.isNull(key)
+                      ? Attribute.name().withValueReset()
+                      : Attribute.name().withValue(params.getString(key))
+                  );
+                  break;
+              case "gender":
+                  userProfileBuilder.apply(
+                    params.isNull(key)
+                      ? Attribute.gender().withValueReset()
+                      : Attribute.gender().withValue(
+                          params.getString(key).equals("female")
+                            ? GenderAttribute.Gender.FEMALE
+                            : params.getString(key).equals("male")
+                              ? GenderAttribute.Gender.MALE
+                              : GenderAttribute.Gender.OTHER
+                        )
+                  );
+                  break;
+              case "age":
+                  userProfileBuilder.apply(
+                    params.isNull(key)
+                      ? Attribute.birthDate().withValueReset()
+                      : Attribute.birthDate().withAge(params.getInt(key))
+                  );
+                  break;
+              case "birthDate":
+                  if (params.isNull(key)) {
+                      userProfileBuilder.apply(
+                        Attribute.birthDate().withValueReset()
+                      );
+                  } else if (params.getType(key) == Array) {
+                      // an array of [ year[, month][, day] ]
+                      ReadableArray date = params.getArray(key);
+                      if (date.size() == 1) {
+                          userProfileBuilder.apply(
+                            Attribute.birthDate().withBirthDate(
+                              date.getInt(0)
+                            )
+                          );
+                      } else if (date.size() == 2) {
+                          userProfileBuilder.apply(
+                            Attribute.birthDate().withBirthDate(
+                              date.getInt(0),
+                              date.getInt(1)
+                            )
+                          );
+                      } else {
+                          userProfileBuilder.apply(
+                            Attribute.birthDate().withBirthDate(
+                              date.getInt(0),
+                              date.getInt(1),
+                              date.getInt(2)
+                            )
+                          );
+                      }
+                  } else {
+                      // number of milliseconds since Unix epoch
+                      Date date = new Date((long)params.getInt(key));
+                      Calendar cal = Calendar.getInstance();
+                      cal.setTime(date);
+                      userProfileBuilder.apply(
+                        Attribute.birthDate().withBirthDate(cal)
+                      );
+                  }
+                  break;
+              case "notificationsEnabled":
+                  userProfileBuilder.apply(
+                    params.isNull(key)
+                      ? Attribute.notificationsEnabled().withValueReset()
+                      : Attribute.notificationsEnabled().withValue(params.getBoolean(key))
+                  );
+                  break;
+              // custom attributes
+              default:
+                  // TODO: come up with a syntax solution to reset custom attributes. `null` will break type checking here
+                  switch (params.getType(key)) {
+                      case Boolean:
+                          userProfileBuilder.apply(
+                            Attribute.customBoolean(key).withValue(params.getBoolean(key))
+                          );
+                          break;
+                      case Number:
+                          userProfileBuilder.apply(
+                            Attribute.customNumber(key).withValue(params.getDouble(key))
+                          );
+                          break;
+                      case String:
+                          String value = params.getString(key);
+                          if (value.startsWith("+") || value.startsWith("-")) {
+                              userProfileBuilder.apply(
+                                Attribute.customCounter(key).withDelta(Double.parseDouble(value))
+                              );
+                          } else {
+                              userProfileBuilder.apply(
+                                Attribute.customString(key).withValue(value)
+                              );
+                          }
+                          break;
+                  }
+          }
+      }
+
+      return userProfileBuilder.build();
     }
 
     static ECommercePrice toECommercePrice(double price) {
diff --git a/node_modules/@npm_redstart/react-native-appmetrica/index.d.ts b/node_modules/@npm_redstart/react-native-appmetrica/index.d.ts
index d0a7ad9..0c2a442 100644
--- a/node_modules/@npm_redstart/react-native-appmetrica/index.d.ts
+++ b/node_modules/@npm_redstart/react-native-appmetrica/index.d.ts
@@ -44,6 +44,7 @@ export interface ActivateConfigProps {
   readonly nativeCrashReporting?: boolean;
   readonly installedAppCollecting?: boolean;
   readonly maxReportsInDatabaseCount?: number;
+  readonly withSessionsAutoTrackingEnabled?: boolean;
   // Only for IOS
   readonly sessionsAutoTracking?: boolean;
   readonly activationAsSessionStart?: boolean;
@@ -83,6 +84,7 @@ export function setUserProfileID(userProfileID?: string): void;
 export function reportError(message: string, reason: unknown): void;
 export function reportEvent(eventName: string, attributes?: unknown): void;
 export function requestAppMetricaDeviceID(listener: DeviceIDListenerType): void;
+export function enableSessionTracking(): Promise<string>;
 
 export function reportUserProfile(userId: string, profile: UserProfileProps);
 
diff --git a/node_modules/@npm_redstart/react-native-appmetrica/index.js b/node_modules/@npm_redstart/react-native-appmetrica/index.js
index 81b449b..9971905 100644
--- a/node_modules/@npm_redstart/react-native-appmetrica/index.js
+++ b/node_modules/@npm_redstart/react-native-appmetrica/index.js
@@ -24,6 +24,10 @@ export default {
     return AppMetrica.getLibraryVersion();
   },
 
+  async enableSessionTracking() {
+    return AppMetrica.enableSessionTracking();
+  },
+
   pauseSession() {
     AppMetrica.pauseSession();
   },
diff --git a/node_modules/@npm_redstart/react-native-appmetrica/ios/AppMetrica.m b/node_modules/@npm_redstart/react-native-appmetrica/ios/AppMetrica.m
index 8c0d5a4..fe1bea2 100644
--- a/node_modules/@npm_redstart/react-native-appmetrica/ios/AppMetrica.m
+++ b/node_modules/@npm_redstart/react-native-appmetrica/ios/AppMetrica.m
@@ -106,7 +106,7 @@ @implementation AppMetrica
 ///
 RCT_EXPORT_METHOD(reportUserProfile:(NSString *)userId profile:(NSDictionary *)profile)
 {
-	[YMMYandexMetrica setUserProfileID:userId];
+	// [YMMYandexMetrica setUserProfileID:userId];
 	YMMUserProfile *userProfile = [AppMetricaUtils userProfileForDictionary:profile];
 	[YMMYandexMetrica reportUserProfile:userProfile onFailure:nil];
 	NSLog(@"user__:");
diff --git a/node_modules/@npm_redstart/react-native-appmetrica/ios/AppMetricaUtils.m b/node_modules/@npm_redstart/react-native-appmetrica/ios/AppMetricaUtils.m
index 87cac03..3876950 100644
--- a/node_modules/@npm_redstart/react-native-appmetrica/ios/AppMetricaUtils.m
+++ b/node_modules/@npm_redstart/react-native-appmetrica/ios/AppMetricaUtils.m
@@ -110,32 +110,101 @@ + (NSString *)stringFromRequestDeviceIDError:(NSError *)error
     return @"UNKNOWN";
 }
 
-+ (YMMUserProfile*)userProfileForDictionary:(NSDictionary *)profileDict {
-	YMMMutableUserProfile *user = [YMMMutableUserProfile new];
-	NSString *name = profileDict[@"name"];
-	if (name != nil) {
-		[user apply:[[YMMProfileAttribute name] withValue:name ]];
-	}
-	NSString *gender = profileDict[@"gender"];
-	if (gender != nil) {
-		if ([gender isEqualToString:@"male"]) {
-			[user apply:[[YMMProfileAttribute gender] withValue:YMMGenderTypeMale]];
-		} else if ([gender isEqualToString:@"female"]) {
-			[user apply:[[YMMProfileAttribute gender] withValue:YMMGenderTypeFemale]];
-		}
-	}
-	NSString *ageString = profileDict[@"age"];
-	if (ageString != nil) {
-		NSInteger age = [ageString integerValue];
-		[user apply:[[YMMProfileAttribute birthDate] withAge:age ]];
-	}
-	NSString *enableNotificationString = profileDict[@"enableNotification"];
-	if (enableNotificationString != nil) {
-		BOOL enableNotification = [enableNotificationString boolValue];
-		[user apply:[[YMMProfileAttribute notificationsEnabled] withValue:enableNotification ]];
-	}
++ (YMMUserProfile*)userProfileForDictionary:(NSDictionary *)attributes {
+	// YMMMutableUserProfile *user = [YMMMutableUserProfile new];
+	// NSString *name = profileDict[@"name"];
+	// if (name != nil) {
+	// 	[user apply:[[YMMProfileAttribute name] withValue:name ]];
+	// }
+	// NSString *gender = profileDict[@"gender"];
+	// if (gender != nil) {
+	// 	if ([gender isEqualToString:@"male"]) {
+	// 		[user apply:[[YMMProfileAttribute gender] withValue:YMMGenderTypeMale]];
+	// 	} else if ([gender isEqualToString:@"female"]) {
+	// 		[user apply:[[YMMProfileAttribute gender] withValue:YMMGenderTypeFemale]];
+	// 	}
+	// }
+	// NSString *ageString = profileDict[@"age"];
+	// if (ageString != nil) {
+	// 	NSInteger age = [ageString integerValue];
+	// 	[user apply:[[YMMProfileAttribute birthDate] withAge:age ]];
+	// }
+	// NSString *enableNotificationString = profileDict[@"enableNotification"];
+	// if (enableNotificationString != nil) {
+	// 	BOOL enableNotification = [enableNotificationString boolValue];
+	// 	[user apply:[[YMMProfileAttribute notificationsEnabled] withValue:enableNotification ]];
+	// }
+
+  YMMMutableUserProfile *profile = [[YMMMutableUserProfile alloc] init];
+  NSMutableArray *attrsArray = [NSMutableArray array];
+  for (NSString* key in attributes) {
+      // predefined attributes
+      if ([key isEqual: @"name"]) {
+          if (attributes[key] == [NSNull null]) {
+              [attrsArray addObject:[[YMMProfileAttribute name] withValueReset]];
+          } else {
+              [attrsArray addObject:[[YMMProfileAttribute name] withValue:[attributes[key] stringValue]]];
+          }
+      } else if ([key isEqual: @"gender"]) {
+          if (attributes[key] == [NSNull null]) {
+              [attrsArray addObject:[[YMMProfileAttribute gender] withValueReset]];
+          } else {
+              [attrsArray addObject:[[YMMProfileAttribute gender] withValue:[[attributes[key] stringValue] isEqual: @"female"] ? YMMGenderTypeFemale : [[attributes[key] stringValue] isEqual: @"male"] ? YMMGenderTypeMale : YMMGenderTypeOther]];
+          }
+      } else if ([key isEqual: @"age"]) {
+          if (attributes[key] == [NSNull null]) {
+              [attrsArray addObject:[[YMMProfileAttribute birthDate] withValueReset]];
+          } else {
+              [attrsArray addObject:[[YMMProfileAttribute birthDate] withAge:[attributes[key] intValue]]];
+          }
+      } else if ([key isEqual: @"birthDate"]) {
+          if (attributes[key] == [NSNull null]) {
+              [attrsArray addObject:[[YMMProfileAttribute birthDate] withValueReset]];
+          } else if ([attributes[key] isKindOfClass:[NSArray class]]) {
+              NSArray *date = [attributes[key] array];
+              if ([date count] == 1) {
+                  [attrsArray addObject:[[YMMProfileAttribute birthDate] withYear:[[date objectAtIndex:0] intValue]]];
+              } else if ([[attributes[key] array] count] == 2) {
+                  [attrsArray addObject:[[YMMProfileAttribute birthDate] withYear:[[date objectAtIndex:0] intValue] month:[[date objectAtIndex:1] intValue]]];
+              } else if ([[attributes[key] array] count] == 3) {
+                  [attrsArray addObject:[[YMMProfileAttribute birthDate] withYear:[[date objectAtIndex:0] intValue] month:[[date objectAtIndex:1] intValue] day:[[date objectAtIndex:2] intValue]]];
+              }
+          } else {
+              // number of milliseconds since Unix epoch
+              NSDate *date = [attributes[key] date];
+              NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian];
+              NSDateComponents *dateComponents =
+                  [gregorian components:(NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay) fromDate:date];
+              [attrsArray addObject:[[YMMProfileAttribute birthDate] withDateComponents:dateComponents]];
+          }
+      } else if ([key isEqual: @"notificationsEnabled"]) {
+          if (attributes[key] == [NSNull null]) {
+              [attrsArray addObject:[[YMMProfileAttribute notificationsEnabled] withValueReset]];
+          } else {
+              [attrsArray addObject:[[YMMProfileAttribute notificationsEnabled] withValue:[attributes[key] boolValue]]];
+          }
+      // custom attributes
+      } else {
+          // TODO: come up with a syntax solution to reset custom attributes. `null` will break type checking here
+          if ([attributes[key] isEqual: @YES] || [attributes[key] isEqual: @NO]) {
+              [attrsArray addObject:[[YMMProfileAttribute customBool:key] withValue:[attributes[key] boolValue]]];
+          } else if ([attributes[key] isKindOfClass:[NSNumber class]]) {
+              [attrsArray addObject:[[YMMProfileAttribute customNumber:key] withValue:[attributes[key] doubleValue]]];
+              // [NSNumber numberWithInt:[attributes[key] intValue]]
+          } else if ([attributes[key] isKindOfClass:[NSString class]]) {
+              if ([attributes[key] hasPrefix:@"+"] || [attributes[key] hasPrefix:@"-"]) {
+                  [attrsArray addObject:[[YMMProfileAttribute customCounter:key] withDelta:[attributes[key] doubleValue]]];
+              } else {
+                  [attrsArray addObject:[[YMMProfileAttribute customString:key] withValue:attributes[key]]];
+              }
+          }
+      }
+  }
+
+  [profile applyFromArray: attrsArray];
+  // [YMMYandexMetrica reportUserProfile:[profile copy] onFailure:NULL];
 	
-	return user;
+	return profile;
 }
 
 + (YMMECommercePrice *)toECommercePriceWithPrice:(NSDecimalNumber *)price {
diff --git a/node_modules/@npm_redstart/react-native-appmetrica/npm_redstart_react-native-appmetrica.podspec b/node_modules/@npm_redstart/react-native-appmetrica/npm_redstart_react-native-appmetrica.podspec
index 444a33e..fc77d64 100644
--- a/node_modules/@npm_redstart/react-native-appmetrica/npm_redstart_react-native-appmetrica.podspec
+++ b/node_modules/@npm_redstart/react-native-appmetrica/npm_redstart_react-native-appmetrica.podspec
@@ -16,5 +16,5 @@ Pod::Spec.new do |s|
   s.requires_arc = true
 
   s.dependency "React"
-  s.dependency 'YandexMobileMetrica', '3.17.0'
+  s.dependency 'YandexMobileMetrica', '4.5.2'
 end

I'll try to come up with a repro, but can't promise that.

Thank you for the provided information. I have tried to reproduce the crash with it, but I couldn't. Please, try to provide a minimal reproducible example, if possible

This issue was closed because it has been stalled for 5 days with no activity.