achorein / expo-share-intent

🚀 Simple share intent in an Expo Native Module
MIT License
128 stars 13 forks source link

hasShareIntent not firing - Standalone Build #11

Closed Roc8Trppn closed 3 months ago

Roc8Trppn commented 4 months ago

Hi,

first of all, thanks a lot for this library, it really saves a lot of time concerning configuration!

In my case however there is the following bug: When i click my app icon in the share dialog from an image of the photo gallery, it does redirect correctly, i.e. it opens my app, but the useShareIntent hook does not fire (at all), no matter if the app is opened in the background or closed.

The App.js file looks like this, and i tested it just to see if it shows any Alert:

export default function App() {
  const { hasShareIntent, shareIntent, error } = useShareIntent();

  useEffect(() => {
    if (hasShareIntent) {
      Alert.alert(
        "HASSHARE INTENT",
        `has share intent: ${hasShareIntent} and also has text: ${shareIntent?.text}`
      );
    }
  }, [hasShareIntent]);

  useEffect(() => {
    if (!!error) {
      Alert.alert("ERROR SHARE INTENT", `has share intent: ${error}`);
    }
  }, [error]);

  return (...)

and nothing happens even when i come from a share intent.

Note: I create my builds with EAS and when I created a dev-build, the app icon is not visible inside of the share dialog (e.g. of an image of the photo gallery), but when I create a standalone build, only then the app icon appears...(Not sure if I need some extra config steps to get it running on a local dev-build...) Anyway, thats why I had to include Alerts, since I cant really debug it well with a standalone build

Details:

Any ideas? Also: if anyone knows how to get it running on a dev-client, please share :)

achorein commented 4 months ago

dev client and simulator build should not defere, make sure you do a expo prebuild --no-install --clean before running the app with expo run:ios

Roc8Trppn commented 4 months ago

Hi @achorein, thanks for the response! Ok, I'll try that.

Concerning the main bug (that the hooks are not firing): Can you reproduce that one? Do you need any additional infos?

Br

achorein commented 4 months ago

i don't reproduce, it always fire for me. If your app is launched it means that your project configuration is ok (scheme, iosActivationRules).

Can you activate the debug mode and show if some logs are relevant

useShareIntent({ debug: true });
Roc8Trppn commented 4 months ago

Ok strange...For some reason now it is working on the dev client (without ejecting from expo managed workflow).

But somehow for production build (created with eas build) it still doesn't fire the shareIntent hook...🤔 Does it have to do with how eas creates the binary?

Concerning your question @achorein: it prints useShareIntent[mount] <app_name> and then once there is a share intent useShareIntent[onChange] <app_name>

simonsturge commented 4 months ago

I am also experiencing this issue. Everything works perfectly running with expo run:ios. Build created with eas build, hook does not fire. App opens as it should after sharing, just nothing happens.

achorein commented 4 months ago

do you have any third party which handle deep link ? (for iOS we need to have access to the deep link url) i'm working on a new version to allow react navigation to work correctly for example

simonsturge commented 4 months ago

Not that I know of. Here's the dependencies and plugins. Anything look suspicious?

I've removed these and still the same behaviour

"@react-native-firebase/analytics": "^19.0.1", "@react-native-firebase/app": "^19.0.1", "@react-native-firebase/crashlytics": "^19.0.1", "@react-native-firebase/messaging": "^19.0.1", "@notifee/react-native": "^7.8.2",

"dependencies": {
    "@backpackapp-io/react-native-toast": "^0.10.0",
    "@fortawesome/fontawesome-svg-core": "^6.5.1",
    "@fortawesome/free-brands-svg-icons": "^6.5.1",
    "@fortawesome/free-regular-svg-icons": "^6.5.1",
    "@fortawesome/free-solid-svg-icons": "^6.5.1",
    "@fortawesome/react-native-fontawesome": "^0.3.0",
    "@georstat/react-native-image-cache": "^3.1.0",
    "@gorhom/bottom-sheet": "^4.6.0",
    "@hcaptcha/react-native-hcaptcha": "^1.6.0",
    "@notifee/react-native": "^7.8.2",
    "@react-native-async-storage/async-storage": "1.21.0",
    "@react-native-clipboard/clipboard": "^1.13.2",
    "@react-native-community/netinfo": "11.1.0",
    "@react-native-firebase/analytics": "^19.0.1",
    "@react-native-firebase/app": "^19.0.1",
    "@react-native-firebase/crashlytics": "^19.0.1",
    "@react-native-firebase/messaging": "^19.0.1",
    "@react-native-masked-view/masked-view": "0.3.0",
    "@react-navigation/bottom-tabs": "^6.5.9",
    "@react-navigation/native": "^6.1.8",
    "@react-navigation/native-stack": "^6.9.14",
    "@shopify/flash-list": "1.6.3",
    "configcat-js": "^9.4.0",
    "crypto-js": "^3.3.0",
    "date-fns": "^3.3.1",
    "expo": "^50.0.11",
    "expo-application": "~5.8.3",
    "expo-build-properties": "~0.11.1",
    "expo-document-picker": "~11.10.1",
    "expo-http-server": "^0.1.0",
    "expo-image": "~1.10.6",
    "expo-share-intent": "^1.0.1",
    "expo-splash-screen": "~0.26.4",
    "expo-system-ui": "~2.9.3",
    "expo-updates": "~0.24.11",
    "i18next": "^23.5.1",
    "intl-pluralrules": "^2.0.1",
    "lodash": "^4.17.21",
    "lottie-react-native": "6.5.1",
    "native-base": "^3.4.28",
    "nativewind": "^4.0.36",
    "react": "18.2.0",
    "react-i18next": "^13.2.2",
    "react-native": "0.73.4",
    "react-native-animated-progress": "^1.0.2",
    "react-native-dialog": "^9.3.0",
    "react-native-file-access": "^3.0.4",
    "react-native-gesture-handler": "~2.14.0",
    "react-native-haptic-feedback": "^2.2.0",
    "react-native-in-app-review": "^4.3.3",
    "react-native-keyboard-aware-scroll-view": "^0.9.5",
    "react-native-localize": "^3.0.2",
    "react-native-modal": "^13.0.1",
    "react-native-purchases": "^7.22.0",
    "react-native-reanimated": "~3.6.2",
    "react-native-recaptcha-that-works": "^2.0.0",
    "react-native-safe-area-context": "4.8.2",
    "react-native-screens": "~3.29.0",
    "react-native-sensitive-info": "^6.0.0-alpha.9",
    "react-native-svg": "14.1.0",
    "react-native-webview": "13.6.4",
    "timed-cache": "^2.0.0"
  }
"plugins": [
      "@react-native-firebase/app",
      "@react-native-firebase/messaging",
      "@react-native-firebase/crashlytics",
      "expo-document-picker",
      [
        "expo-build-properties",
        {
          "android": {
            "usesCleartextTraffic": true,
            "extraMavenRepos": [
              "../../node_modules/@notifee/react-native/android/libs"
            ]
          },
          "ios": {
            "useFrameworks": "static"
          }
        }
      ],
      [
        "expo-share-intent",
        {
          "iosActivationRules": {
            "NSExtensionActivationSupportsText": true,
            "NSExtensionActivationSupportsWebURLWithMaxCount": 1,
            "NSExtensionActivationSupportsWebPageWithMaxCount": 1
          },
          "androidIntentFilters": ["text/*", "image/*"],
          "androidMultiIntentFilters": ["text/*", "image/*"]
        }
      ]
    ]
achorein commented 4 months ago

🤔 i haven't tested with static build

Roc8Trppn commented 4 months ago

Ah that could be the reason...we're using them too:


"plugins": [
      "expo-localization",
      "expo-apple-authentication",
      "expo-font",
      "react-native-iap",
      "@react-native-firebase/app",
      "@react-native-firebase/crashlytics",
      [
        "expo-share-intent",
        {
          "iosActivationRules": {
            "NSExtensionActivationSupportsImageWithMaxCount": 1,
            "NSExtensionActivationSupportsFileWithMaxCount": 1
          }
        }
      ],
      [
        "expo-build-properties",
        {
          "ios": {
            "useFrameworks": "static"
          }
        }
      ],
      [
        "expo-share-intent",
        {
          "iosActivationRules": {
            "NSExtensionActivationSupportsImageWithMaxCount": 1
          }
        }
      ]
    ]
simonsturge commented 4 months ago

I have removed firebase & static frameworks, unfortunately still seeing the issue

simonsturge commented 4 months ago

Ah that could be the reason...we're using them too:

"plugins": [
      "expo-localization",
      "expo-apple-authentication",
      "expo-font",
      "react-native-iap",
      "@react-native-firebase/app",
      "@react-native-firebase/crashlytics",
      [
        "expo-share-intent",
        {
          "iosActivationRules": {
            "NSExtensionActivationSupportsImageWithMaxCount": 1,
            "NSExtensionActivationSupportsFileWithMaxCount": 1
          }
        }
      ],
      [
        "expo-build-properties",
        {
          "ios": {
            "useFrameworks": "static"
          }
        }
      ],
      [
        "expo-share-intent",
        {
          "iosActivationRules": {
            "NSExtensionActivationSupportsImageWithMaxCount": 1
          }
        }
      ]
    ]

do you mind including your full dependencies? I removed almost all packages from my project and it started working, so I think there must be something in here that's causing the problem. Maybe we can compare and see what packages we have in common

"dependencies": {
    "@backpackapp-io/react-native-toast": "^0.10.0",
    "@fortawesome/fontawesome-svg-core": "^6.5.1",
    "@fortawesome/free-brands-svg-icons": "^6.5.1",
    "@fortawesome/free-regular-svg-icons": "^6.5.1",
    "@fortawesome/free-solid-svg-icons": "^6.5.1",
    "@fortawesome/react-native-fontawesome": "^0.3.0",
    "@georstat/react-native-image-cache": "^3.1.0",
    "@gorhom/bottom-sheet": "^4.6.0",
    "@hcaptcha/react-native-hcaptcha": "^1.6.0",
    "@notifee/react-native": "^7.8.2",
    "@react-native-async-storage/async-storage": "1.21.0",
    "@react-native-clipboard/clipboard": "^1.13.2",
    "@react-native-community/netinfo": "11.1.0",
    "@react-native-firebase/analytics": "^19.0.1",
    "@react-native-firebase/app": "^19.0.1",
    "@react-native-firebase/crashlytics": "^19.0.1",
    "@react-native-firebase/messaging": "^19.0.1",
    "@react-native-masked-view/masked-view": "0.3.0",
    "@react-navigation/bottom-tabs": "^6.5.9",
    "@react-navigation/native": "^6.1.8",
    "@react-navigation/native-stack": "^6.9.14",
    "@shopify/flash-list": "1.6.3",
    "configcat-js": "^9.4.0",
    "crypto-js": "^3.3.0",
    "date-fns": "^3.3.1",
    "expo": "^50.0.11",
    "expo-application": "~5.8.3",
    "expo-build-properties": "~0.11.1",
    "expo-document-picker": "~11.10.1",
    "expo-http-server": "^0.1.0",
    "expo-image": "~1.10.6",
    "expo-share-intent": "^1.0.1",
    "expo-splash-screen": "~0.26.4",
    "expo-system-ui": "~2.9.3",
    "expo-updates": "~0.24.11",
    "i18next": "^23.5.1",
    "intl-pluralrules": "^2.0.1",
    "lodash": "^4.17.21",
    "lottie-react-native": "6.5.1",
    "native-base": "^3.4.28",
    "nativewind": "^4.0.36",
    "react": "18.2.0",
    "react-i18next": "^13.2.2",
    "react-native": "0.73.4",
    "react-native-animated-progress": "^1.0.2",
    "react-native-dialog": "^9.3.0",
    "react-native-file-access": "^3.0.4",
    "react-native-gesture-handler": "~2.14.0",
    "react-native-haptic-feedback": "^2.2.0",
    "react-native-in-app-review": "^4.3.3",
    "react-native-keyboard-aware-scroll-view": "^0.9.5",
    "react-native-localize": "^3.0.2",
    "react-native-modal": "^13.0.1",
    "react-native-purchases": "^7.22.0",
    "react-native-reanimated": "~3.6.2",
    "react-native-recaptcha-that-works": "^2.0.0",
    "react-native-safe-area-context": "4.8.2",
    "react-native-screens": "~3.29.0",
    "react-native-sensitive-info": "^6.0.0-alpha.9",
    "react-native-svg": "14.1.0",
    "react-native-webview": "13.6.4",
    "timed-cache": "^2.0.0"
  },
  "devDependencies": {
    "@babel/core": "^7.22.20",
    "@babel/runtime": "^7.24.0",
    "@babel/preset-env": "^7.22.20",
    "@react-native-community/eslint-config": "^3.2.0",
    "@react-native/eslint-config": "^0.72.2",
    "@react-native/metro-config": "^0.73.5",
    "@tsconfig/react-native": "^3.0.2",
    "@types/crypto-js": "^4.1.1",
    "@types/jest": "^29.5.5",
    "@types/lodash": "^4.14.199",
    "@types/metro-config": "^0.76.3",
    "@types/react": "^18.2.22",
    "@types/react-native-animated-progress": "^1.0.1",
    "@types/react-native-dotenv": "^0.2.0",
    "@types/react-test-renderer": "^18.0.2",
    "@types/timed-cache": "^2.0.1",
    "@typescript-eslint/eslint-plugin": "^6.7.2",
    "@typescript-eslint/parser": "^6.7.2",
    "babel-jest": "^29.7.0",
    "babel-plugin-module-resolver": "^5.0.0",
    "eslint": "^8.50.0",
    "eslint-config-prettier": "^9.0.0",
    "eslint-import-resolver-babel-module": "^5.3.2",
    "eslint-plugin-import": "^2.28.1",
    "eslint-plugin-jest": "^27.6.1",
    "eslint-plugin-prettier": "^5.0.0",
    "jest": "^29.7.0",
    "metro-react-native-babel-preset": "0.77.0",
    "patch-package": "^8.0.0",
    "postinstall-postinstall": "^2.1.0",
    "prettier": "3.0.3",
    "react-native-dotenv": "^3.4.9",
    "react-native-svg-transformer": "^1.1.0",
    "react-native-url-polyfill": "^2.0.0",
    "react-test-renderer": "18.2.0",
    "tailwindcss": "^3.4.1",
    "typescript": "^5.3.0"
  },
achorein commented 4 months ago

Do you have your useShareIntent hook in your top App component ? It should be use before any other Provider. (FYI: next version will add a ShareIntentProvider to persist data on multiple screen)

If it's already the case maybe the dependancy problem it's on the native module side :/

simonsturge commented 4 months ago

After doing some more digging, in my case, it's caused by expo-updates.

Disabling updates allows the share intent to work:

"updates": {
      "enabled": false,
      "url": "https://u.expo.dev/...."
    }

I'm still doing some more testing in release mode, but I'm seeing a couple other potential issues. They could be just issues with my project, or general issues, not sure yet.

  1. Sharing once works fine. If I then go back to the other app and share the same thing again, the share sheet freezes. Sometime it will open the share modal, and then freeze.

  2. Sharing unusual text causes the app to crash. Could be just my app, not sure yet. Text like this for example, possibly line breaks, or when the text is in multiple elements: text

joshmohrer commented 4 months ago

My situation matches the OP -- everything works until it gets back to my app and the share intent doesnt fire. I removed another library that touched deep links and now it works again. So some kind of collision there.

achorein commented 4 months ago

@simonsturg thanks for your test ! can you open 2 new issues to address theses problem ? 👍

@joshmohrer great ! do you have the dependancy name to make a reproductable example ?

Can your try with this hierarchy :

const { shareIntent ) = useShareIntent({ debug: true });
console.log(shareIntent);

return (
  <Provider1>
    <Provider2>
       <App />
     <Provider2>
  </Provider1>
)
joshmohrer commented 4 months ago

Thank you @achorein you're a legend :)

Its a bit esoteric but the package causing the problem is airbridge-expo-sdk and/or its companion airbirdge-react-native-sdk, both of which enable the Airbridge analytics platform. Specifically there is some deep link handling which may be getting in the way.

    "airbridge-expo-sdk": "^2.6.0",
    "airbridge-react-native-sdk": "^2.6.0",

If I remove these, it works great, but with them it does not work. I am migrating an existing project to Expo 50 from bare react native, and have react-native-share-intent working alongside this package in production.

Currently i'm using it with the hierarchy you suggest, in my App.tsx.

my app's icon shows up correctly where it should, and the share brings me back to my app. I see this in the console when I background and then bring app to foreground with the share.

 DEBUG  useShareIntent[to-background] reset intent
 DEBUG  useShareIntent[active] refresh intent
Roc8Trppn commented 4 months ago

After doing some more digging, in my case, it's caused by expo-updates.

Disabling updates allows the share intent to work:

"updates": {
      "enabled": false,
      "url": "https://u.expo.dev/...."
    }

I'm still doing some more testing in release mode, but I'm seeing a couple other potential issues. They could be just issues with my project, or general issues, not sure yet.

  1. Sharing once works fine. If I then go back to the other app and share the same thing again, the share sheet freezes. Sometime it will open the share modal, and then freeze.
  2. Sharing unusual text causes the app to crash. Could be just my app, not sure yet. Text like this for example, possibly line breaks, or when the text is in multiple elements: text

Wow good catch! I removed expo-updates and it works now for my standalone version! nice one @simonsturge

simonsturge commented 4 months ago

@achorein just wondering if you have any ideas on what might cause the incompatibility with expo-updates, and if you think it's fixable?

i've disabled it in my app for now, however, I'd really like to be able to enable it at some point in the future

joshmohrer commented 4 months ago

I kicked the tires a bit on my end and believe airbridge sdk is creating a similar conflict as expo-updates. Both seem to break expo-share-intent in a similar way. Without either in my project, share intent works great.

If I have to pick those packages or this one, I think I choose this one. its too useful :)

Let me know if I can support this effort with any additional info.

achorein commented 4 months ago

I don't know why it's causing a problem, i need to make a minimal reproduction example to investigate. I don't have the time right now but will do later.

joshmohrer commented 4 months ago

@achorein i realize this would be a guess, but do you think it’s possible that the problem here would be resolved using expo router instead of react navigation?

achorein commented 4 months ago

@achorein i realize this would be a guess, but do you think it’s possible that the problem here would be resolved using expo router instead of react navigation?

Don't think so

achorein commented 4 months ago

@joshmohrer when using airbridge-expo-sdk you have to configure deeplink manualy (https://help.airbridge.io/en/developers/expo-sdk#deep-link-setup).

With react-navigation just add a listener in your linking configuration (see example here)

Airbridge.deeplink.setDeeplinkListener((deeplink) => {
   listener(deeplink);
})

any lib that intercepts deeplinks must be configured manually.

joshmohrer commented 4 months ago

@achorein i did just that, copied all your code exactly from navigator in your example as well as that airbridge listener but still didn’t work. As soon as I removed airbridge again it worked.

joshmohrer commented 4 months ago

Providing a little more detail @achorein it would console log a link ending in sharekey but with no file info. I can reproduce if helpful.

joshmohrer commented 3 months ago

When I have this in place

  Airbridge.deeplink.setDeeplinkListener((deeplink) => {
    // code that will run when app is opened with deep-link or deferred-deep-link
    // deeplink = YOUR_SCHEME://...
    console.log("its me airbridge listener", deeplink);
  });

it logs

 INFO  [Airbridge RN] add deeplink listener
 LOG  its me airbridge listener wave-app://dataUrl=wave-appShareKey#file
[CoreFoundation] Not updating lastKnownShmemState in CFPrefsPlistSource<0x6000030506c0> (Domain: group.com.ma.waveapp, User: kCFPreferencesCurrentUser, ByHost: No, Container:
(null), Contents Need Refresh: Yes): 170 -> 179
 DEBUG  useShareIntent[to-background] reset intent
 INFO  [Airbridge RN] [deeplink] wave-app://dataUrl=wave-appShareKey#file
 LOG  its me airbridge listener wave-app://dataUrl=wave-appShareKey#file
 DEBUG  useShareIntent[active] refresh intent
 DEBUG  useShareIntent[refresh] null
achorein commented 3 months ago

can you try this :

  Airbridge.deeplink.setDeeplinkListener((deeplink) => {
    // import { getShareIntent } from "expo-share-intent";
    if (deeplink?.startsWith(`${Constants.expoConfig?.scheme}://dataUrl`)) {
      getShareIntent(deeplink);
    }
  })

this will trigger a change event from the native module (retreived by hook or provider)

joshmohrer commented 3 months ago

That worked! @achorein you are a legend. Thank you!

achorein commented 3 months ago

@simonsturge can you give me your useShareIntent[refresh] debug log when used with eas build ? (maybe it's not starting with ${Constants.expoConfig?.scheme}://dataUrl)

joshmohrer commented 3 months ago

It works fine with expo-updates for me now as well, btw.

achorein commented 3 months ago

I added expo-update in the basic example without any problems (simulator and eas with dev-client).

I also added some compatibilty check in v1.2.1 if you still have problem give it a try.

felixaa commented 3 months ago

Seems like I have a similar issue. With updates: { enabled: true } I can't get the shareIntent to fire. With it disabled everything works fine.

In order to reproduce I have to run the app in release configuration like: bun ios -d --configuration release

felixaa commented 3 months ago

I added expo-update in the basic example without any problems (simulator and eas with dev-client).

I also added some compatibilty check in v1.2.1 if you still have problem give it a try.

Did you try this in release configuration also?

achorein commented 3 months ago

closing the issue for now, i will handle the expo-updates part in https://github.com/achorein/expo-share-intent/issues/46.