webdevcody / file-drive

MIT License
241 stars 126 forks source link

Not able to download the files #2

Closed dushyanth31 closed 7 months ago

dushyanth31 commented 8 months ago

Hello @webdevcody ,

I'm getting this error today stating that upstream image response failed and {"code":"InvalidStoragePath","message":"Invalid storage path: ************* is not a valid UUID string."}, but yesterday it works fine. Is this problem with the Convex or something else.

Got this console log error: Failed to load resource: the server responded with a status of 400 ()

dushyanth31 commented 7 months ago

Yes, Solved:

Step 1: Setting Up Your Convex Function to Store File URLs When you upload a file using Convex, ensure you store not just the file metadata but also the URL to access the file. This is done in your mutation function when creating a file entry in your database.

// convex/files.ts

export const createFile = mutation({
args: {
name: v.string(),
fileId: v.id("_storage"),
orgId: v.string(),
type: fileTypes,
},
async handler(ctx, args) {
const hasAccess = await hasAccessToOrg(ctx, args.orgId);

if (!hasAccess) {
  throw new ConvexError("you do not have access to this org");
}

const fileUrl = await ctx.storage.getUrl(args.fileId);

if (!fileUrl) {
  throw new ConvexError("file not found");
}

await ctx.db.insert("files", {
  name: args.name,
  orgId: args.orgId,
  fileId: args.fileId,
  type: args.type,
  userId: hasAccess.user._id,
  url: fileUrl,
});
},
});

Step 2: Add to your schema

export default defineSchema({
  files: defineTable({ 
    name: v.string(),
    type: fileTypes,
    orgId: v.string(),
    fileId: v.id('_storage'),
    userId: v.id('users'),
    shouldDelete: v.optional(v.boolean()),
    url: v.string(),
   })

Step 3: Apply the changes to this file:

//src/app/dashboard/_components/file-card.tsx

{file.type === "image" && ( <Image alt={file.name} width="200" height="100" src={file.url} /> )}

Step 3: you'll display each file with a download button. When the button is clicked, the file URL stored in your database is used to initiate the download.

//_components/file-actions.tsx

 Just replace this with existing one or just add the changes,
<DropdownMenu>
        <DropdownMenuTrigger>
          <MoreVertical />
        </DropdownMenuTrigger>
        <DropdownMenuContent>
          <DropdownMenuItem
            onClick={() => {
              window.open(file.url, "_blank");
            }}
            className="flex gap-1 items-center cursor-pointer"
          >
            <FileIcon className="w-4 h-4" /> Download
          </DropdownMenuItem>

Hope it helps. Thank you.