invertase / react-native-firebase

πŸ”₯ A well-tested feature-rich modular Firebase implementation for React Native. Supports both iOS & Android platforms for all Firebase services.
https://rnfirebase.io
Other
11.63k stars 2.2k forks source link

[πŸ›] πŸ”₯ In App Messaging CTA Button Not Working On iOS #6861

Closed pristinejudah closed 1 year ago

pristinejudah commented 1 year ago

Issue

After successfully installing @react-native-firebase/in-app-messaging as well as @react-native-firebase/app and @react-native-firebase/analytics on to my app the app works fine both in the development and production environment, even the app analytics works perfectly in logging events to Firebase. The issue now is that whenever an in-app Card Message is sent from the console and it's delivered to my iOS users, the pop-up CTA button when clicked on it closes on the card despite that I indicated on the console that the pop-up CTA should be linked to a webpage.

Project Files

Javascript

Click To Expand

#### `package.json`: ``` { "name": "my-app", "version": "1.0.0", "main": "index.js", "scripts": { "start": "expo start --dev-client", "android": "expo run:android --variant devDebug", "android-prod": "expo run:android --variant prodDebug", "android-staging": "expo run:android --variant stagingDebug", "ios": "expo run:ios --scheme 'estatemanager-Development'", "ios-prod": "expo run:ios --scheme 'estatemanager'", "ios-staging": "expo run:ios --scheme 'estatemanager-Staging'", "build": "eas build --profile devRelease --platform all", "build-staging": "eas build --profile stagingRelease --platform all", "build-prod": "eas build --profile productionRelease --platform all", "build-android": "eas build --profile devRelease --platform android", "build-android-staging": "eas build --profile stagingRelease --platform android", "build-android-prod": "eas build --profile productionRelease --platform android", "build-ios": "eas build --profile devRelease --platform ios", "build-ios-staging": "eas build --profile stagingRelease --platform ios", "build-ios-prod": "eas build --profile productionRelease --platform ios", "web": "expo start --web", "postinstall": "patch-package", "adb-reverse": "adb reverse tcp:8081 tcp:8081" }, "dependencies": { "@expo/vector-icons": "^13.0.0", "@notifee/react-native": "^7.1.0", "@react-native-async-storage/async-storage": "~1.17.3", "@react-native-clipboard/clipboard": "^1.11.1", "@react-native-community/datetimepicker": "6.5.2", "@react-native-community/netinfo": "9.3.5", "@react-native-firebase/analytics": "^16.4.6", "@react-native-firebase/app": "^16.4.6", "@react-native-firebase/in-app-messaging": "^16.4.6", "@react-native-firebase/messaging": "^16.4.6", "@react-native-firebase/perf": "^16.4.6", "@react-native-picker/picker": "2.4.8", "@react-navigation/drawer": "^6.5.0", "@react-navigation/native": "^6.0.13", "@react-navigation/native-stack": "^6.9.1", "@react-navigation/stack": "^6.3.1", "@sentry/react-native": "4.2.2", "axios": "^0.27.2", "buffer": "^6.0.3", "d3-scale": "^4.0.2", "deprecated-react-native-prop-types": "^2.3.0", "expo": "^47.0.0", "expo-application": "~5.0.1", "expo-asset": "~8.6.2", "expo-av": "~13.0.1", "expo-blur": "~12.0.1", "expo-calendar": "~11.0.1", "expo-camera": "~13.0.0", "expo-clipboard": "~4.0.1", "expo-contacts": "~11.0.1", "expo-device": "~5.0.0", "expo-document-picker": "~11.0.1", "expo-file-system": "~15.1.1", "expo-font": "~11.0.1", "expo-image-picker": "~14.0.1", "expo-intent-launcher": "~10.3.1", "expo-linear-gradient": "~12.0.1", "expo-localization": "~14.0.0", "expo-location": "~15.0.1", "expo-media-library": "~15.0.0", "expo-secure-store": "~12.0.0", "expo-sharing": "~11.0.1", "expo-sms": "~11.0.0", "expo-splash-screen": "~0.17.5", "expo-status-bar": "~1.4.2", "expo-updates": "~0.15.5", "expo-web-browser": "~12.0.0", "google-libphonenumber": "^3.2.30", "i18n-js": "^4.1.1", "libphonenumber-js": "^1.10.13", "lodash": "^4.17.21", "lottie-react-native": "5.1.4", "moment": "^2.29.4", "moment-timezone": "^0.5.38", "numeral": "^2.0.6", "patch-package": "^6.4.7", "postinstall-postinstall": "^2.1.0", "react": "18.1.0", "react-dom": "18.1.0", "react-native": "0.70.5", "react-native-animatable": "^1.3.3", "react-native-calendar-strip": "^2.2.6", "react-native-config": "^1.4.11", "react-native-country-picker-modal": "^2.0.0", "react-native-encrypted-storage": "^4.0.2", "react-native-fast-image": "^8.6.1", "react-native-gesture-handler": "~2.8.0", "react-native-global-props": "^1.1.5", "react-native-material-ripple": "^0.9.1", "react-native-modal-datetime-picker": "^14.0.0", "react-native-modern-datepicker": "^1.0.0-beta.91", "react-native-option-menu": "^1.1.3", "react-native-otp-verify": "^1.0.5", "react-native-pager-view": "6.0.1", "react-native-qrcode-svg": "^6.1.2", "react-native-quick-actions": "^0.3.13", "react-native-reanimated": "~2.12.0", "react-native-safe-area-context": "4.4.1", "react-native-safe-area-view": "^1.1.1", "react-native-screen": "^1.0.1", "react-native-screens": "~3.18.0", "react-native-slide-to-unlock": "^0.1.6", "react-native-smooth-pincode-input": "^1.0.9", "react-native-snap-carousel": "^3.9.1", "react-native-speedometer-chart": "^0.7.5", "react-native-status-bar-height": "^2.6.0", "react-native-svg": "13.4.0", "react-native-svg-charts": "^5.4.0", "react-native-tab-view": "^3.1.1", "react-native-vector-icons": "^9.2.0", "react-native-walkthrough-tooltip": "^1.4.0", "react-native-web": "~0.18.7", "react-native-webview": "11.23.1", "react-native-week-view": "^0.24.0", "react-redux": "^8.0.4", "redux": "^4.2.0", "redux-persist": "^6.0.0", "redux-thunk": "^2.4.1", "rn-sliding-up-panel": "^2.4.6", "semver": "^7.3.7", "styled-components": "^5.3.6", "text-encoding-polyfill": "^0.6.7", "yup": "^0.32.11" }, "devDependencies": { "@babel/core": "^7.19.3", "@types/jest": "^29.0.3", "@types/react": "~18.0.24", "@types/react-native": "~0.70.6", "@types/react-test-renderer": "^18.0.0", "typescript": "^4.6.3" }, "private": true } ``` #### `firebase.json` for react-native-firebase v6: ``` { "react-native": { "google_analytics_automatic_screen_reporting_enabled": true } } ```

iOS

Click To Expand

#### `ios/Podfile`: - [ ] I'm not using Pods - [x] I'm using Pods and my Podfile looks like: ``` require File.join(File.dirname(`node --print "require.resolve('expo/package.json')"`), "scripts/autolinking") require File.join(File.dirname(`node --print "require.resolve('react-native/package.json')"`), "scripts/react_native_pods") require File.join(File.dirname(`node --print "require.resolve('@react-native-community/cli-platform-ios/package.json')"`), "native_modules") require 'json' podfile_properties = JSON.parse(File.read(File.join(__dir__, 'Podfile.properties.json'))) rescue {} platform :ios, podfile_properties['ios.deploymentTarget'] || '13' install! 'cocoapods', :deterministic_uuids => false abstract_target 'app' do use_expo_modules! config = use_native_modules! use_frameworks! :linkage => podfile_properties['ios.useFrameworks'].to_sym if podfile_properties['ios.useFrameworks'] pod 'Firebase', :modular_headers => true pod 'FirebaseCore', :modular_headers => true # pod 'FirebaseCoreInternal', :modular_headers => true # pod 'FirebaseStorageInternal', :modular_headers => true pod 'FirebaseCoreExtension', :modular_headers => true # pod 'FirebaseAppCheckInterop', :modular_headers => true # pod 'FirebaseAuthInterop', :modular_headers => true pod 'FirebaseMessagingInterop', :modular_headers => true pod 'FirebasePerformance', :modular_headers => true pod 'FirebaseRemoteConfig', :modular_headers => true # pod 'GTMSessionFetcher', :modular_headers => true pod 'GoogleUtilities', :modular_headers => true # Flags change depending on the env values. flags = get_default_flags() use_react_native!( :path => config[:reactNativePath], :hermes_enabled => flags[:hermes_enabled] || podfile_properties['expo.jsEngine'] == 'hermes', :fabric_enabled => flags[:fabric_enabled], # An absolute path to your application root. :app_path => "#{Dir.pwd}/.." ) target 'my-app' do #Production specific pods end target 'my-app-Development' do #Development specific pods end target 'my-app-Staging' do #Staging specific pods end # Uncomment to opt-in to using Flipper # Note that if you have use_frameworks! enabled, Flipper will not work # # if !ENV['CI'] # use_flipper!() # end post_install do |installer| react_native_post_install(installer) __apply_Xcode_12_5_M1_post_install_workaround(installer) # This is necessary for Xcode 14, because it signs resource bundles by default # when building for devices. installer.target_installation_results.pod_target_installation_results .each do |pod_name, target_installation_result| target_installation_result.resource_bundle_targets.each do |resource_bundle_target| resource_bundle_target.build_configurations.each do |config| config.build_settings['CODE_SIGNING_ALLOWED'] = 'NO' end end end end post_integrate do |installer| begin expo_patch_react_imports!(installer) rescue => e Pod::UI.warn e end end end ``` #### `AppDelegate.m`: ``` #import #import "RNQuickActionManager.h" #import "AppDelegate.h" #import #import #import #import #import #import #if RCT_NEW_ARCH_ENABLED #import #import #import #import #import #import #import static NSString *const kRNConcurrentRoot = @"concurrentRoot"; @interface AppDelegate () { RCTTurboModuleManager *_turboModuleManager; RCTSurfacePresenterBridgeAdapter *_bridgeAdapter; std::shared_ptr _reactNativeConfig; facebook::react::ContextContainer::Shared _contextContainer; } @end #endif @implementation AppDelegate - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { [FIRApp configure]; RCTAppSetupPrepareApp(application); RCTBridge *bridge = [self.reactDelegate createBridgeWithDelegate:self launchOptions:launchOptions]; #if RCT_NEW_ARCH_ENABLED _contextContainer = std::make_shared(); _reactNativeConfig = std::make_shared(); _contextContainer->insert("ReactNativeConfig", _reactNativeConfig); _bridgeAdapter = [[RCTSurfacePresenterBridgeAdapter alloc] initWithBridge:bridge contextContainer:_contextContainer]; bridge.surfacePresenter = _bridgeAdapter.surfacePresenter; #endif NSDictionary *initProps = [self prepareInitialProps]; UIView *rootView = [self.reactDelegate createRootViewWithBridge:bridge moduleName:@"main" initialProperties:initProps]; rootView.backgroundColor = [UIColor whiteColor]; self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds]; UIViewController *rootViewController = [self.reactDelegate createRootViewController]; rootViewController.view = rootView; self.window.rootViewController = rootViewController; [self.window makeKeyAndVisible]; [super application:application didFinishLaunchingWithOptions:launchOptions]; return YES; } - (NSArray> *)extraModulesForBridge:(RCTBridge *)bridge { // If you'd like to export some custom RCTBridgeModules, add them here! return @[]; } /// This method controls whether the `concurrentRoot`feature of React18 is turned on or off. /// /// @see: https://reactjs.org/blog/2022/03/29/react-v18.html /// @note: This requires to be rendering on Fabric (i.e. on the New Architecture). /// @return: `true` if the `concurrentRoot` feture is enabled. Otherwise, it returns `false`. - (BOOL)concurrentRootEnabled { // Switch this bool to turn on and off the concurrent root return true; } - (NSDictionary *)prepareInitialProps { NSMutableDictionary *initProps = [NSMutableDictionary new]; #if RCT_NEW_ARCH_ENABLED initProps[kRNConcurrentRoot] = @([self concurrentRootEnabled]); #endif return initProps; } - (NSURL *)sourceURLForBridge:(RCTBridge *)bridge { #if DEBUG return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index"]; #else return [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"]; #endif } // Linking API - (BOOL)application:(UIApplication *)application openURL:(NSURL *)url options:(NSDictionary *)options { return [super application:application openURL:url options:options] || [RCTLinkingManager application:application openURL:url options:options]; } // Universal Links - (BOOL)application:(UIApplication *)application continueUserActivity:(nonnull NSUserActivity *)userActivity restorationHandler:(nonnull void (^)(NSArray> * _Nullable))restorationHandler { BOOL result = [RCTLinkingManager application:application continueUserActivity:userActivity restorationHandler:restorationHandler]; return [super application:application continueUserActivity:userActivity restorationHandler:restorationHandler] || result; } // Explicitly define remote notification delegates to ensure compatibility with some third-party libraries - (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken { return [super application:application didRegisterForRemoteNotificationsWithDeviceToken:deviceToken]; } // Explicitly define remote notification delegates to ensure compatibility with some third-party libraries - (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error { return [super application:application didFailToRegisterForRemoteNotificationsWithError:error]; } // Explicitly define remote notification delegates to ensure compatibility with some third-party libraries - (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler { return [super application:application didReceiveRemoteNotification:userInfo fetchCompletionHandler:completionHandler]; } #if RCT_NEW_ARCH_ENABLED #pragma mark - RCTCxxBridgeDelegate - (std::unique_ptr)jsExecutorFactoryForBridge:(RCTBridge *)bridge { _turboModuleManager = [[RCTTurboModuleManager alloc] initWithBridge:bridge delegate:self jsInvoker:bridge.jsCallInvoker]; return RCTAppSetupDefaultJsExecutorFactory(bridge, _turboModuleManager); } #pragma mark RCTTurboModuleManagerDelegate - (Class)getModuleClassFromName:(const char *)name { return RCTCoreModulesClassProvider(name); } - (std::shared_ptr)getTurboModule:(const std::string &)name jsInvoker:(std::shared_ptr)jsInvoker { return nullptr; } - (std::shared_ptr)getTurboModule:(const std::string &)name initParams: (const facebook::react::ObjCTurboModule::InitParams &)params { return nullptr; } - (id)getModuleInstanceFromClass:(Class)moduleClass { return RCTAppSetupDefaultModuleFromClass(moduleClass); } #endif - (void)application:(UIApplication *)application performActionForShortcutItem:(UIApplicationShortcutItem *)shortcutItem completionHandler:(void (^)(BOOL succeeded)) completionHandler { [RNQuickActionManager onQuickActionPress:shortcutItem completionHandler:completionHandler]; } @end ```


Android

Click To Expand

#### Have you converted to AndroidX? - [ ] my application is an AndroidX application? - [ ] I am using `android/gradle.settings` `jetifier=true` for Android compatibility? - [ ] I am using the NPM package `jetifier` for react-native compatibility? #### `android/build.gradle`: ```groovy // N/A ``` #### `android/app/build.gradle`: ```groovy // N/A ``` #### `android/settings.gradle`: ```groovy // N/A ``` #### `MainApplication.java`: ```java // N/A ``` #### `AndroidManifest.xml`: ```xml ```


Environment

Click To Expand

**`react-native info` output:** ``` System: OS: macOS 13.0.1 CPU: (8) arm64 Apple M1 Memory: 63.58 MB / 16.00 GB Shell: 5.8.1 - /bin/zsh Binaries: Node: 16.16.0 - /usr/local/bin/node Yarn: 1.22.19 - /usr/local/bin/yarn npm: 8.11.0 - /usr/local/bin/npm Watchman: 2022.07.04.00 - /opt/homebrew/bin/watchman Managers: CocoaPods: 1.11.3 - /usr/local/bin/pod SDKs: iOS SDK: Platforms: DriverKit 22.1, iOS 16.1, macOS 13.0, tvOS 16.1, watchOS 9.1 Android SDK: Android NDK: 22.1.7171670 IDEs: Android Studio: 2021.2 AI-212.5712.43.2112.8609683 Xcode: 14.1/14B47b - /usr/bin/xcodebuild Languages: Java: 11.0.15 - /usr/bin/javac npmPackages: @react-native-community/cli: Not Found react: 18.1.0 => 18.1.0 react-native: 0.70.5 => 0.70.5 react-native-macos: Not Found npmGlobalPackages: *react-native*: Not Found ``` - **Platform that you're experiencing the issue on**: - [x] iOS - [ ] Android - [ ] **iOS** but have not tested behavior on Android - [ ] **Android** but have not tested behavior on iOS - [ ] Both - **`react-native-firebase` version you're using that has this issue:** - `e.g. 5.4.3` - **`Firebase` module(s) you're using that has the issue:** - `e.g. Instance ID` - **Are you using `TypeScript`?** - `Y/N` & `VERSION`


mikehardy commented 1 year ago

I'm not sure this is supportable:


  pod 'Firebase', :modular_headers => true
  pod 'FirebaseCore', :modular_headers => true
  # pod 'FirebaseCoreInternal', :modular_headers => true  
  # pod 'FirebaseStorageInternal', :modular_headers => true
  pod 'FirebaseCoreExtension', :modular_headers => true
  # pod 'FirebaseAppCheckInterop', :modular_headers => true
  # pod 'FirebaseAuthInterop', :modular_headers => true
  pod 'FirebaseMessagingInterop', :modular_headers => true
  pod 'FirebasePerformance', :modular_headers => true
  pod 'FirebaseRemoteConfig', :modular_headers => true
  # pod 'GTMSessionFetcher', :modular_headers => true
  pod 'GoogleUtilities', :modular_headers => true

Are you actually using use_frameworks! :linkage => :static as required in our installation docs (since I can't tell what the variables resolve to, I'm not sure) or are you using this modular headers workaround?

There are strange side effects with the modular headers hacks and in general I don't investigate problems when it is used, as it is not a supported configuration

pristinejudah commented 1 year ago

Thanks @mikehardy for the suggestions, I've done as you suggested but I'm still getting the same issue of the CTA button just dismissing the message pop-up

nguyensonghao94 commented 1 year ago

@pristinejudah do you have any solution for it. It is still not working on iOS with me :(

github-actions[bot] commented 1 year ago

Hello πŸ‘‹, to help manage issues we automatically close stale issues.

This issue has been automatically marked as stale because it has not had activity for quite some time.Has this issue been fixed, or does it still require attention?

This issue will be closed in 15 days if no further activity occurs.

Thank you for your contributions.

dsumayan21 commented 1 year ago

i am having the same issue, any one got a fix for this?

pristinejudah commented 1 year ago

@nguyensonghao94 @dsumayan21 I didn't get a direct solution for this so the workaround I did was to implemented Firebase Dynamic link using the guide here https://rnfirebase.io/dynamic-links/usage then I created dynamic links for each weblink I wanted to use for the Firebase messaging CTA

github-actions[bot] commented 1 year ago

Hello πŸ‘‹, to help manage issues we automatically close stale issues.

This issue has been automatically marked as stale because it has not had activity for quite some time.Has this issue been fixed, or does it still require attention?

This issue will be closed in 15 days if no further activity occurs.

Thank you for your contributions.

jamesbautista1 commented 1 year ago

@pristinejudah do you already have a solution on it?

pristinejudah commented 1 year ago

So like I've said previously, using react native firebase dynamic link fixed the issue for me

On Wed, 21 Jun 2023, 12:13 James Russel C. Bautista, < @.***> wrote:

@pristinejudah https://github.com/pristinejudah do you already have a solution on it?

β€” Reply to this email directly, view it on GitHub https://github.com/invertase/react-native-firebase/issues/6861#issuecomment-1600645505, or unsubscribe https://github.com/notifications/unsubscribe-auth/AYYL53MC5V5MYKLY3JJACCDXMLJONANCNFSM6AAAAAAUGBA744 . You are receiving this because you were mentioned.Message ID: @.***>

jamesbautista1 commented 1 year ago

So like I've said previously, using react native firebase dynamic link fixed the issue for me … On Wed, 21 Jun 2023, 12:13 James Russel C. Bautista, < @.> wrote: @pristinejudah https://github.com/pristinejudah do you already have a solution on it? β€” Reply to this email directly, view it on GitHub <#6861 (comment)>, or unsubscribe https://github.com/notifications/unsubscribe-auth/AYYL53MC5V5MYKLY3JJACCDXMLJONANCNFSM6AAAAAAUGBA744 . You are receiving this because you were mentioned.Message ID: @.> Do you mean you put the firebase dynamic link in the CTA button to make it work in the campaign editor for in app messaging?

kauamelo commented 5 months ago

I'm with the exact same issue here. The only solution mentioned in this issue was to use 'Firebase Dynamic Links', but it seems like it is deprecated, so we should not be using that:

image

https://firebase.google.com/docs/dynamic-links?hl=en&authuser=0&_gl=1*165me6x*_ga*MjA4NTk1NjkzNC4xNzAyNTYzMzAw*_ga_CW55HF8NVT*MTcxMjA2NDM3Ni44My4xLjE3MTIwNjUzOTQuMC4wLjA.

Is this a problem in the @react-native-firebase/in-app-messaging ? Should we re-open this?

Has anyone found another workaround?

kauamelo commented 5 months ago

@pristinejudah @nguyensonghao94 @dsumayan21 @jamesbautista1 Is it still working for you guys? I created this issue here: https://github.com/invertase/react-native-firebase/issues/7730 since for me it's not working with Firebase Dynamic Links as you guys suggested. Also, it's deprecated.

Did you guys find a solution?

pristinejudah commented 5 months ago

@kauamelo I'm now using deep links in place of dynamic links and I also built out a custom form of in-app messaging that covers more use cases and serves our business needs better than the Firebase in-app messaging. If you need help setting up deep links or creating a custom in-app message I'm happy to help in any way.

kauamelo commented 5 months ago

Alright, thank you very much! I'll need to think here a bit what I'm gonna do then... Firebase in-app messaging seemed like a good enough solution for my case if the 'action button' worked on iOS.

But alright, I'll get in touch in case I decide to create a custom in-app message solution :) I appreciate your availability!