Comments (6)
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.
from react-native-sdk.
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.
from react-native-sdk.
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.
from react-native-sdk.
I am using
@npm_redstart/[email protected]
which is a fork of an official module, which is also patched by me on a project level. Quite messy, yes.
[email protected]
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.
from react-native-sdk.
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
from react-native-sdk.
This issue was closed because it has been stalled for 5 days with no activity.
from react-native-sdk.
Related Issues (20)
- Plugin with id 'maven' not found. HOT 4
- Qonversion Data Safety HOT 2
- App Crash in Production HOT 2
- Configuration with name 'compile' not found. HOT 3
- Build Failed with React Native 0.69.3 / react-native-qonversion 3.3.2 HOT 3
- Undefined symbols for architecture x86_64 HOT 6
- Xcode 12 support
- iOS products are empty on new version HOT 3
- Issue during android build HOT 1
- Crash during Qonversion.offerings() HOT 7
- skProduct is null HOT 18
- Question: Does Qonversion finish consumable purchases? If not, how would I do this? HOT 3
- Do you support react native's fabric architecture? HOT 3
- Problem with syncHistoricalData HOT 3
- Entitlement data after purchase HOT 4
- Cannot install in RN 0.65 with React 17.0.2 HOT 4
- Permission object having active flag to false HOT 1
- IAP receipt error HOT 2
- React-native linking deprecation warning HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from react-native-sdk.