Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[🐛] 🔥 No suitable URL request handler found for ph:// #2868

Open
1 of 8 tasks
fathulfahmy opened this issue Jan 1, 2025 · 10 comments
Open
1 of 8 tasks

[🐛] 🔥 No suitable URL request handler found for ph:// #2868

fathulfahmy opened this issue Jan 1, 2025 · 10 comments

Comments

@fathulfahmy
Copy link

Issue

Image picker returns error No suitable URL request handler found for ph:// on iOS (Expo Go) on initial render, but works fine after error is dismissed.

Steps to reproduce

Steps to reproduce the behavior:

  1. Go to Channel screen
  2. Click on add attachment icon +
  3. Image picker bottom sheet will appear and disappear immediately
  4. Click on add attachment icon + again
  5. See error
  6. Dismiss error
  7. Click on add attachment icon + again
  8. Pick image
  9. Send image

Expected behavior

Image picker bottom sheet returns no error initially on iOS (Expo Go)

Project Related Information

Customization

Click To Expand

import React from "react";
import { Platform } from "react-native";

import { router } from "expo-router";
import { Channel, MessageInput, MessageList, MessagePinnedHeader } from "stream-chat-expo";

import { LoadingStateScreen } from "@/components/screens";
import { useChat } from "@/lib/stream-chat/chat-store";

export const Conversation = () => {
  const { channel, setThread } = useChat();

  if (!channel) return <LoadingStateScreen />;

  return (
    <Channel channel={channel} keyboardVerticalOffset={90}>
      <MessageList
        onThreadSelect={(thread) => {
          setThread(thread);
          router.push(`/chat/${channel.cid}/thread/${thread?.cid}`);
        }}
      />
      <MessageInput />
    </Channel>
  );
};

Offline support

  • I have enabled offline support.
  • The feature I'm having does not occur when offline support is disabled. (stripe out if not applicable)

Environment

Click To Expand

package.json:

{
  "name": "the-barter-app",
  "license": "0BSD",
  "main": "expo-router/entry",
  "version": "52.0.43",
  "scripts": {
    "start": "expo start",
    "reset-project": "node ./scripts/reset-project.js",
    "android": "expo run:android",
    "ios": "expo run:ios",
    "web": "expo start --web",
    "test": "jest --watchAll",
    "lint": "expo lint"
  },
  "jest": {
    "preset": "jest-expo"
  },
  "dependencies": {
    "@dev-plugins/react-query": "^0.1.0",
    "@expo/vector-icons": "^14.0.2",
    "@hookform/resolvers": "^3.9.1",
    "@op-engineering/op-sqlite": "^11.2.8",
    "@react-native-community/netinfo": "11.4.1",
    "@react-navigation/bottom-tabs": "^7.0.0",
    "@react-navigation/material-top-tabs": "^7.0.18",
    "@react-navigation/native": "^7.0.0",
    "@shopify/flash-list": "1.7.1",
    "@stream-io/flat-list-mvcp": "^0.10.3",
    "@stripe/stripe-react-native": "0.38.6",
    "@tanstack/react-query": "^5.62.0",
    "axios": "^1.7.8",
    "dayjs": "^1.11.13",
    "expo": "~52.0.11",
    "expo-av": "~15.0.1",
    "expo-blur": "~14.0.1",
    "expo-clipboard": "~7.0.0",
    "expo-constants": "~17.0.3",
    "expo-dev-client": "~5.0.5",
    "expo-document-picker": "~13.0.1",
    "expo-file-system": "~18.0.6",
    "expo-font": "~13.0.1",
    "expo-haptics": "~14.0.0",
    "expo-image-manipulator": "~13.0.5",
    "expo-image-picker": "~16.0.3",
    "expo-insights": "~0.8.1",
    "expo-linking": "~7.0.3",
    "expo-media-library": "~17.0.4",
    "expo-network": "~7.0.3",
    "expo-router": "~4.0.9",
    "expo-secure-store": "~14.0.0",
    "expo-sharing": "~13.0.0",
    "expo-splash-screen": "~0.29.13",
    "expo-status-bar": "~2.0.0",
    "expo-symbols": "~0.2.0",
    "expo-system-ui": "~4.0.4",
    "expo-updates": "~0.26.9",
    "expo-web-browser": "~14.0.1",
    "react": "18.3.1",
    "react-dom": "18.3.1",
    "react-hook-form": "^7.53.2",
    "react-native": "0.76.3",
    "react-native-gesture-handler": "~2.20.2",
    "react-native-keyboard-aware-scroll-view": "^0.9.5",
    "react-native-pager-view": "6.5.1",
    "react-native-paper": "^5.12.5",
    "react-native-paper-dates": "^0.22.27",
    "react-native-quick-sqlite": "^8.2.7",
    "react-native-reanimated": "~3.16.1",
    "react-native-reanimated-carousel": "^3.5.1",
    "react-native-safe-area-context": "^4.12.0",
    "react-native-screens": "~4.1.0",
    "react-native-svg": "15.8.0",
    "react-native-web": "~0.19.13",
    "react-native-webview": "13.12.2",
    "stream-chat-expo": "^6.0.1",
    "zod": "^3.23.8",
    "zustand": "^5.0.1"
  },
  "devDependencies": {
    "@babel/core": "^7.25.2",
    "@tanstack/eslint-plugin-query": "^5.62.1",
    "@trivago/prettier-plugin-sort-imports": "^4.3.0",
    "@types/jest": "^29.5.12",
    "@types/react": "~18.3.12",
    "@types/react-test-renderer": "^18.3.0",
    "eslint": "^8.57.0",
    "eslint-config-expo": "~8.0.1",
    "eslint-config-prettier": "^9.1.0",
    "eslint-plugin-prettier": "^5.2.1",
    "jest": "^29.2.1",
    "jest-expo": "~52.0.2",
    "prettier": "^3.4.1",
    "react-test-renderer": "18.3.1",
    "typescript": "^5.3.3"
  }
}

react-native info output:

 OUTPUT GOES HERE
  • Platform that you're experiencing the issue on:
    • iOS
    • Android
    • iOS but have not tested behavior on Android
    • Android but have not tested behavior on iOS
    • Both
  • stream-chat-react-native version you're using that has this issue:
    • stream-chat-expo: ^6.0.1
  • Device/Emulator info:
    • I am using a physical device
    • OS version: Expo SDK 52
    • Device/Emulator: Expo Go

Additional context

Screenshots

Click To Expand

error screenshot error gif


@khushal87
Copy link
Member

Hey @fathulfahmy, what's your stream-chat-expo, expo and expo-media-library version?

@fathulfahmy
Copy link
Author

fathulfahmy commented Jan 2, 2025

Hey @fathulfahmy, what's your stream-chat-expo, expo and expo-media-library version?

Expo version: 52.0.20
Stream chat version: 6.0.1
Expo media library: 17.0.4

Full configuration in environment tab included in opened issue

@khushal87
Copy link
Member

@fathulfahmy you are running the app on new architecture, right?

@fathulfahmy
Copy link
Author

@fathulfahmy you are running the app on new architecture, right?

Yes, as it is the default behavior for Expo SDK 52

@khushal87
Copy link
Member

khushal87 commented Jan 2, 2025

Hey @fathulfahmy the latest of expo 52 is 52.0.23 how are you on expo 52.0.43? Can you run npx expo install --fix on your project and see if that fixes your issue?

@fathulfahmy
Copy link
Author

fathulfahmy commented Jan 2, 2025

@khushal87 I apologize as I misreferenced expo version number. Corrected expo version is 52.0.20. I have also ran npx expo install --fix but the issue still persists.

Full package.json { "name": "the-barter-app", "license": "0BSD", "main": "expo-router/entry", "version": "52.0.43", "scripts": { "start": "expo start", "reset-project": "node ./scripts/reset-project.js", "android": "expo run:android", "ios": "expo run:ios", "web": "expo start --web", "test": "jest --watchAll", "lint": "expo lint" }, "jest": { "preset": "jest-expo" }, "dependencies": { "@dev-plugins/react-query": "^0.1.0", "@expo/vector-icons": "^14.0.2", "@hookform/resolvers": "^3.9.1", "@op-engineering/op-sqlite": "^11.2.8", "@react-native-community/netinfo": "11.4.1", "@react-navigation/bottom-tabs": "^7.0.0", "@react-navigation/material-top-tabs": "^7.0.18", "@react-navigation/native": "^7.0.0", "@shopify/flash-list": "1.7.1", "@stream-io/flat-list-mvcp": "^0.10.3", "@stripe/stripe-react-native": "0.38.6", "@tanstack/react-query": "^5.62.0", "axios": "^1.7.8", "dayjs": "^1.11.13", "expo": "~52.0.20", "expo-av": "~15.0.1", "expo-blur": "~14.0.1", "expo-clipboard": "~7.0.0", "expo-constants": "~17.0.3", "expo-dev-client": "~5.0.8", "expo-document-picker": "~13.0.1", "expo-file-system": "~18.0.6", "expo-font": "~13.0.1", "expo-haptics": "~14.0.0", "expo-image-manipulator": "~13.0.5", "expo-image-picker": "~16.0.3", "expo-insights": "~0.8.1", "expo-linking": "~7.0.3", "expo-media-library": "~17.0.4", "expo-network": "~7.0.3", "expo-router": "~4.0.15", "expo-secure-store": "~14.0.0", "expo-sharing": "~13.0.0", "expo-splash-screen": "~0.29.13", "expo-status-bar": "~2.0.0", "expo-symbols": "~0.2.0", "expo-system-ui": "~4.0.4", "expo-updates": "~0.26.9", "expo-web-browser": "~14.0.1", "react": "18.3.1", "react-content-loader": "^7.0.2", "react-dom": "18.3.1", "react-hook-form": "^7.53.2", "react-native": "0.76.5", "react-native-gesture-handler": "~2.20.2", "react-native-keyboard-aware-scroll-view": "^0.9.5", "react-native-pager-view": "6.5.1", "react-native-paper": "^5.12.5", "react-native-paper-dates": "^0.22.27", "react-native-quick-sqlite": "^8.2.7", "react-native-reanimated": "~3.16.1", "react-native-safe-area-context": "4.12.0", "react-native-screens": "~4.4.0", "react-native-svg": "15.8.0", "react-native-web": "~0.19.13", "react-native-webview": "13.12.5", "stream-chat-expo": "^6.0.1", "zod": "^3.23.8", "zustand": "^5.0.1" }, "devDependencies": { "@babel/core": "^7.25.2", "@tanstack/eslint-plugin-query": "^5.62.1", "@trivago/prettier-plugin-sort-imports": "^4.3.0", "@types/jest": "^29.5.12", "@types/react": "~18.3.12", "@types/react-test-renderer": "^18.3.0", "eslint": "^8.57.0", "eslint-config-expo": "~8.0.1", "eslint-config-prettier": "^9.1.0", "eslint-plugin-prettier": "^5.2.1", "jest": "^29.2.1", "jest-expo": "~52.0.2", "prettier": "^3.4.1", "react-test-renderer": "18.3.1", "typescript": "^5.3.3" } }

And from Expo docs, new architecture shouldn't be disabled for Expo Go to work starting from Expo SDK52

Starting SDK 52, Expo Go only supports the New Architecture since all Expo libraries and third-party libraries included in Expo Go support the New Architecture. Note that the Go app is not intended to be used as a development environment for real-world apps.

@khushal87
Copy link
Member

It works for expo ~52.0.20 and expo-media-library ~17.0.4 for me, expo-image-manipulator being ~13.0.5. Did you clear your cache and run the app again?

@fathulfahmy
Copy link
Author

fathulfahmy commented Jan 2, 2025

It works for expo ~52.0.20 and expo-media-library ~17.0.4 for me, expo-image-manipulator being ~13.0.5. Did you clear your cache and run the app again?

The issue still persists upon opening camera roll initially. The issue only occurs on iOS but not on Android.
No suitable URL request handler found for ph://0CE37DD5-0032-45BB-8153-D3E3E5B43CD4/L0/001

I have tried:

  • Cleared bundler caches on Windows
  • Run npx expo install --fix
  • Update expo expo-media-library stream-chat-expo
  • Built a new project without EAS
  • Built a new project with EAS
Channel
import React from "react";

import { router } from "expo-router";
import { Channel, MessageInput, MessageList } from "stream-chat-expo";

import { LoadingStateScreen } from "@/components/screens";
import { useChat } from "@/lib/stream-chat/chat-store";

export const Conversation = () => {
  const { channel, setThread } = useChat();

  if (!channel) return <LoadingStateScreen />;

  return (
    <Channel channel={channel} keyboardVerticalOffset={90}>
      <MessageList
        onThreadSelect={(thread) => {
          setThread(thread);
          router.push(`/chat/${channel.cid}/thread/${thread?.cid}`);
        }}
      />
      <MessageInput />
    </Channel>
  );
};

@khushal87
Copy link
Member

khushal87 commented Jan 3, 2025

Yep, it was an iOS-only issue on new architecture, too, but we fixed it, and the version upgrade doesn't seem to cause it for us anymore, so it's weird that it happens for you. We will try to triage more and get back to you if we find something.

The bottom sheet being open and closed is a known issue for us.

@fathulfahmy
Copy link
Author

I have found a workaround to this matter. I created a custom attach button component from the official Stream Chat React Native v6 documentation and Expo ImagePicker.

Result

Open screenshot

Code

Custom Attach Button
import { useActionSheet } from "@expo/react-native-action-sheet";
import * as ImagePicker from "expo-image-picker";
import { AttachButton, useMessageInputContext } from "stream-chat-expo";

export const CustomAttachButton = () => {
  const { showActionSheetWithOptions } = useActionSheet();
  const { pickFile, uploadNewImage } = useMessageInputContext();

  const pickImageFromGallery = async () => {
    const permission = await ImagePicker.requestMediaLibraryPermissionsAsync();
    if (permission.granted) {
      let result = await ImagePicker.launchImageLibraryAsync({
        allowsMultipleSelection: true,
      });
      if (!result.canceled) {
        result.assets.forEach((image) => {
          uploadNewImage({
            uri: image.uri,
          });
        });
      }
    } else {
      alert("Permission to media library is required");
    }
  };

  const pickImageFromCamera = async () => {
    const permission = await ImagePicker.requestCameraPermissionsAsync();
    if (permission.granted) {
      let result = await ImagePicker.launchCameraAsync({
        allowsEditing: true,
      });
      if (!result.canceled) {
        uploadNewImage({
          uri: result.assets[0].uri,
        });
      }
    } else {
      alert("Permission to camera is required");
    }
  };

  const onPress = () => {
    // Same interface as https://facebook.github.io/react-native/docs/actionsheetios.html
    showActionSheetWithOptions(
      {
        cancelButtonIndex: 3,
        destructiveButtonIndex: 3,
        options: ["Photo Library", "Camera", "Files", "Cancel"],
      },
      (buttonIndex) => {
        switch (buttonIndex) {
          case 0:
            pickImageFromGallery();
            break;
          case 1:
            pickImageFromCamera();
            break;
          case 2:
            pickFile();
            break;
          default:
            break;
        }
      },
    );
  };

  return <AttachButton handleOnPress={onPress} />;
};
Channel
import React from "react";

import { router } from "expo-router";
import { Channel, MessageInput, MessageList } from "stream-chat-expo";

import { useChat } from "@/lib/stream-chat/chat-store";

import { CustomAttachButton } from "./custom-attach-button";

export const Conversation = () => {
  /* ======================================== HOOKS */
  const { channel, setThread } = useChat();

  /* ======================================== RETURNS */
  if (!channel) return null;

  return (
    <Channel channel={channel} keyboardVerticalOffset={90} AttachButton={CustomAttachButton}>
      <MessageList
        onThreadSelect={(thread) => {
          setThread(thread);
          router.push(`/chat/${channel.cid}/thread/${thread?.cid}`);
        }}
      />
      <MessageInput />
    </Channel>
  );
};
Root Layout
const RootLayout = () => {
  const theme = AppLightTheme;

  useOnlineManager();
  useAppState(onAppStateChange);
  useReactQueryDevTools(queryClient);

  return (
    <PaperProvider theme={theme}>
      <QueryClientProvider client={queryClient}>
        <AuthTokenProvider>
          <SafeAreaProvider>
            <GestureHandlerRootView>
              {/* Wrap root layout with ActionSheetProvider */}
              <ActionSheetProvider>
                <StreamChatProvider>
                  <StripePaymentProvider>
                    <StatusBar style="light" backgroundColor={theme.colors.primary} />
                    <Stack>
                      <Stack.Screen name="(tabs)" options={{ headerShown: false }} />
                      <Stack.Screen name="(auth)" options={{ headerShown: false }} />
                      <Stack.Screen name="+not-found" />
                    </Stack>
                    <StatusDialog />
                    <ConfirmationDialog />
                    <Notification />
                  </StripePaymentProvider>
                </StreamChatProvider>
              </ActionSheetProvider>
            </GestureHandlerRootView>
          </SafeAreaProvider>
        </AuthTokenProvider>
      </QueryClientProvider>
    </PaperProvider>
  );
};

export default RootLayout;

References

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants