clerk / javascript

Official Javascript repository for Clerk authentication
https://clerk.com
MIT License
1.04k stars 235 forks source link

user.setProfileImage does not accept a blob when called from Expo app #1085

Closed andrewbateman closed 1 year ago

andrewbateman commented 1 year ago

Package + Version

Dependencies + versions

{  
  "dependencies": {
    "react": "18.2.0",
    "react-native": "0.71.6",
    "nativewind": "^2.0.11",
    "@clerk/clerk-expo": "^0.16.3",
    "expo": "~48.0.9",
    "expo-image-picker": "~14.1.1"
  }
}

Browser/OS

N/A

Description

When trying to update a user's profile image from an Expo app, the call to user.setProfileImage does not accept a blob returned from a call to fetch. The promise rejects with this error.

{"code":"request_body_invalid","message":"Request body invalid","longMessage":"The request body is invalid. Please consult the API documentation for more information.","meta":{}}

I have also tried converting the blob to a File object and passing that instead, which resulted in the same error.

Is there a better way to generate the blob from the picked file?

import {useUser } from "@clerk/clerk-expo";
import { useState } from "react";
import { View, Image, Pressable, Text } from "react-native";
import * as ImagePicker from "expo-image-picker";

export default function AccountScreen() {
  const { user } = useUser();

  const [imageUrl, setImageUrl] = useState<string|undefined>(user?.profileImageUrl || "");
  async function updatePhoto(imageUrl: string) {
    const response = await fetch(imageUrl);
    const blob = await response.blob();
    user?.setProfileImage({ file: blob });
  }

  const pickImage = async () => {
    // No permissions request is necessary for launching the image library
    const result = await ImagePicker.launchImageLibraryAsync({
      mediaTypes: ImagePicker.MediaTypeOptions.Images,
      allowsEditing: true,
      aspect: [1, 1],
      quality: 0.5,
      selectionLimit: 1,
    });

    if (!result.canceled) {
      setImageUrl(result.assets[0].uri);
      await updatePhoto(result.assets[0].uri);
    }
  };

  const removeImage = async () => {
    await user?.setProfileImage({ file: null });
    setImageUrl(user?.profileImageUrl);
  };

  return (
    <View className="p-4 space-y-4 divide-y divide-brand">
      <View className="flex flex-row items-center space-x-2 pt-4">
        <View className="h-20 w-20 rounded-full border-2 border-brand">
          <Image
            source={{ uri: imageUrl }}
            alt={user?.fullName || ""}
            className="h-full w-full rounded-full"
            style={{ resizeMode: "cover" }}
          />
        </View>
        <View className="space-y-2">
          <Pressable onPress={pickImage}>
            <Text className="text-brand-700">Choose Image</Text>
          </Pressable>
          <Pressable onPress={removeImage}>
            <Text className="text-brand">Remove Image</Text>
          </Pressable>
        </View>
      </View>

    </View>
  );
}

Simulator Screen Recording - iPhone 14 Pro Max - 2023-04-20 at 18 17 30

perkinsjr commented 1 year ago

Hi there we are aware of this issue and are working on updating some code on our side.

We will then be able to handle expo updates using base64 strings.

slgtmko commented 1 year ago

Any update on this one? Thanks!

gkats commented 1 year ago

Hey all, we're working on adding support for base64 encoded images in user.setProfileImage(). It's probably going to be out by end of next week.

Will provide another update once the feature is out. Thanks everybody for being patient.

gkats commented 1 year ago

Hello all, a fix for the problem has been released. The User.setProfileImage method now accepts a file as a base64 encoded data URL.

Usage:

user.setProfileImage({ file: "data:image/png;base64,<base64-encoded-string>" });

The latest clerkJS (v4.47.0) and expo (v0.18.0) releases include the fix.

Closing the issue, but feel free to reopen if something's not right.

slgtmko commented 1 year ago

Working for me with @clerk/clerk-expo@0.18.0 🎉

clerk-cookie commented 2 months ago

This issue has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.