supabase / supabase-js

An isomorphic Javascript client for Supabase. Query your Supabase database, subscribe to realtime events, upload and download files, browse typescript examples, invoke postgres functions via rpc, invoke supabase edge functions, query pgvector.
https://supabase.com
MIT License
2.92k stars 224 forks source link

Supabase JS Storage not returning ID #923

Open simonsayssa opened 6 months ago

simonsayssa commented 6 months ago

Supabase JS is not returning the ID of the uploaded file. After checking the storage API latest update, the ID is being returned after calling the "upload" API. However, in the supabase-js storage.upload() function, only the path (string) is returned. Kindly add the file id to the response since some users will link the file id to their database tables.

Steps to Reproduce:

const { data: uploadFileData, error: uploadFileError } = await supabaseClient
    .storage
    .from(bucketName)
    .upload(path, file, {
      {},
      cacheControl: "3600",
      upsert: true
    });

the id was not returned.

Expected Behavior: the response data object should contain id.

After going through the code in supabase-js package, I noticed that the ID is being returned by the storage API but the structure of the returned object was {"path": string}. Kindly fix it to { id: string; path: string; fullPath: string }

sumitbhanushali commented 6 months ago

@simonsayssa can you elaborate more on this? I am not able to reproduce this, also after digging into code, i found that in supabase-js, there is one function named 'storage' which exports whole storage-js client

get storage() {
    return new SupabaseStorageClient(this.storageUrl, this.headers, this.fetch)
}
ssayssa commented 6 months ago

the bug is under the "upload" function in StorageFileApi.ts. If you notice in the code above, the issue is not the storage function, but in the supabaseClient.storage().from().upload() function. The code is currently:

async upload(
    path: string,
    fileBody: FileBody,
    fileOptions?: FileOptions
  ): Promise<
    | {
        data: { path: string }
        error: null
      }
    | {
        data: null
        error: StorageError
      }
  > {
    return this.uploadOrUpdate('POST', path, fileBody, fileOptions)
  }

while it should be:

async upload(
    path: string,
    fileBody: FileBody,
    fileOptions?: FileOptions
  ): Promise<
    | {
        data: { id: string; path: string; fullPath: string }
        error: null
      }
    | {
        data: null
        error: StorageError
      }
  > {
    return this.uploadOrUpdate('POST', path, fileBody, fileOptions)
  }

The issue is solved by adding the id and fullPath to the response interface of the upload function in StorageFileApi.ts under the storage-js package

sumitbhanushali commented 6 months ago

did you check with git blame whether this was intentional.

Also, you can raise the PR for the fix

nikitastryuk commented 4 months ago

Any updates? Id field is needed a lot

matheusdamiao commented 2 months ago

Facing the same problem here, but I need the fullPath property, which is also not implemented in the interface.

matheusdamiao commented 2 months ago

The only workaround that worked for me it was to cast using 'as'

const data = await supabase.storage
          .from(bucket)
          .upload(file.name, file);
const castedResponse = data as SupabaseUploadResponse; 

implementing my own interface:

interface SupabaseUploadResponse {
  data: { path: string; fullPath: string } | null;
  error: any | null;
}

You guys can just add an ID and be happy. It's not the best solution, but as I said, it's a workaround.