C# Reference v0.0

C# Client Library

supabaseView on GitHub

This reference documents every object and method available in Supabase's C# library, supabase-csharp. You can use Supabase to interact with your Postgres database, listen to database changes, invoke Deno Edge Functions, build login and user management functionality, and manage large files.


Installing

Install from NuGet

You can install Supabase package from nuget.org

Terminal

_10
dotnet add package supabase-csharp


Initializing

Initializing a new client is pretty straightforward. Find your project url and public key from the admin panel and pass it into your client initialization function.

Supabase is heavily dependent on Models deriving from BaseModel. To interact with the API, one must have the associated model (see example) specified.

Leverage Table, PrimaryKey, and Column attributes to specify names of classes/properties that are different from their C# Versions.


_10
var url = Environment.GetEnvironmentVariable("SUPABASE_URL");
_10
var key = Environment.GetEnvironmentVariable("SUPABASE_KEY");
_10
_10
var options = new Supabase.SupabaseOptions
_10
{
_10
AutoConnectRealtime = true
_10
};
_10
_10
var supabase = new Supabase.Client(url, key, options);
_10
await supabase.InitializeAsync();


Fetch data

Performs vertical filtering with SELECT.

  • LINQ expressions do not currently support parsing embedded resource columns. For these cases, string will need to be used.
  • When using string Column Names to select, they must match names in database, not names specified on model properties.
  • Additional information on modeling + querying Joins and Inner Joins can be found in the postgrest-csharp README
  • By default, Supabase projects will return a maximum of 1,000 rows. This setting can be changed in Project API Settings. It's recommended that you keep it low to limit the payload size of accidental or malicious requests. You can use range() queries to paginate through your data.
  • From() can be combined with Modifiers
  • From() can be combined with Filters
  • If using the Supabase hosted platform apikey is technically a reserved keyword, since the API gateway will pluck it out for authentication. It should be avoided as a column name.

_19
// Given the following Model (City.cs)
_19
[Table("cities")]
_19
class City : BaseModel
_19
{
_19
[PrimaryKey("id")]
_19
public int Id { get; set; }
_19
_19
[Column("name")]
_19
public string Name { get; set; }
_19
_19
[Column("country_id")]
_19
public int CountryId { get; set; }
_19
_19
//... etc.
_19
}
_19
_19
// A result can be fetched like so.
_19
var result = await supabase.From<City>().Get();
_19
var cities = result.Models


Insert data

Performs an INSERT into the table.


_20
[Table("cities")]
_20
class City : BaseModel
_20
{
_20
[PrimaryKey("id", false)]
_20
public int Id { get; set; }
_20
_20
[Column("name")]
_20
public string Name { get; set; }
_20
_20
[Column("country_id")]
_20
public int CountryId { get; set; }
_20
}
_20
_20
var model = new City
_20
{
_20
Name = "The Shire",
_20
CountryId = 554
_20
};
_20
_20
await supabase.From<City>().Insert(model);


Update data

Performs an UPDATE on the table.

  • Update() is typically called using a model as an argument or from a hydrated model.

_10
var update = await supabase
_10
.From<City>()
_10
.Where(x => x.Name == "Auckland")
_10
.Set(x => x.Name, "Middle Earth")
_10
.Update();


Upsert data

Performs an UPSERT into the table.

  • Primary keys should be included in the data payload in order for an update to work correctly.
  • Primary keys must be natural, not surrogate. There are however, workarounds for surrogate primary keys.

_10
var model = new City
_10
{
_10
Id = 554,
_10
Name = "Middle Earth"
_10
};
_10
_10
await supabase.From<City>().Upsert(model);


Delete data

Performs a DELETE on the table.

  • Delete() should always be combined with Filters to target the item(s) you wish to delete.

_10
await supabase
_10
.From<City>()
_10
.Where(x => x.Id == 342)
_10
.Delete();


Call a Postgres function

You can call stored procedures as a "Remote Procedure Call".

That's a fancy way of saying that you can put some logic into your database then call it from anywhere. It's especially useful when the logic rarely changes - like password resets and updates.


_10
await supabase.Rpc("hello_world", null);


Using filters

Filters allow you to only return rows that match certain conditions.

Filters can be used on Select(), Update(), and Delete() queries.

Note: LINQ expressions do not currently support parsing embedded resource columns. For these cases, string will need to be used.


_10
var result = await supabase.From<City>()
_10
.Select(x => new object[] { x.Name, x.CountryId })
_10
.Where(x => x.Name == "The Shire")
_10
.Single();


Column is equal to a value

Finds all rows whose value on the stated column exactly matches the specified value.


_10
var result = await supabase.From<City>()
_10
.Where(x => x.Name == "Bali")
_10
.Get();


Column is not equal to a value

Finds all rows whose value on the stated column doesn't match the specified value.


_10
var result = await supabase.From<City>()
_10
.Select(x => new object[] { x.Name, x.CountryId })
_10
.Where(x => x.Name != "Bali")
_10
.Get();


Column is greater than a value

Finds all rows whose value on the stated column is greater than the specified value.


_10
var result = await supabase.From<City>()
_10
.Select(x => new object[] { x.Name, x.CountryId })
_10
.Where(x => x.CountryId > 250)
_10
.Get();


Column is greater than or equal to a value

Finds all rows whose value on the stated column is greater than or equal to the specified value.


_10
var result = await supabase.From<City>()
_10
.Select(x => new object[] { x.Name, x.CountryId })
_10
.Where(x => x.CountryId >= 250)
_10
.Get();


Column is less than a value

Finds all rows whose value on the stated column is less than the specified value.


_10
var result = await supabase.From<City>()
_10
.Select("name, country_id")
_10
.Where(x => x.CountryId < 250)
_10
.Get();


Column is less than or equal to a value

Finds all rows whose value on the stated column is less than or equal to the specified value.


_10
var result = await supabase.From<City>()
_10
.Where(x => x.CountryId <= 250)
_10
.Get();


Column matches a pattern

Finds all rows whose value in the stated column matches the supplied pattern (case sensitive).


_10
var result = await supabase.From<City>()
_10
.Filter(x => x.Name, Operator.Like, "%la%")
_10
.Get();


Column matches a case-insensitive pattern

Finds all rows whose value in the stated column matches the supplied pattern (case insensitive).


_10
await supabase.From<City>()
_10
.Filter(x => x.Name, Operator.ILike, "%la%")
_10
.Get();


Column is a value

A check for exact equality (null, true, false), finds all rows whose value on the stated column exactly match the specified value.


_10
var result = await supabase.From<City>()
_10
.Where(x => x.Name == null
_10
.Get();


Column is in an array

Finds all rows whose value on the stated column is found on the specified values.


_10
var result = await supabase.From<City>()
_10
.Filter(x => x.Name, Operator.In, new List<object> { "Rio de Janiero", "San Francisco" })
_10
.Get();


Column contains every element in a value


_10
var result = await supabase.From<City>()
_10
.Filter(x => x.MainExports, Operator.Contains, new List<object> { "oil", "fish" })
_10
.Get();


Contained by value


_10
var result = await supabase.From<City>()
_10
.Filter(x => x.MainExports, Operator.ContainedIn, new List<object> { "oil", "fish" })
_10
.Get();


Match a string

Finds all rows whose tsvector value on the stated column matches to_tsquery(query).


Match an associated value

  • Finds a model given a class (useful when hydrating models and correlating with database)
  • Finds all rows whose columns match the specified Dictionary<string, string> object.

_10
var city = new City
_10
{
_10
Id = 224,
_10
Name = "Atlanta"
_10
};
_10
_10
var model = supabase.From<City>().Match(city).Single();


Don't match the filter

Finds all rows which doesn't satisfy the filter.


_10
var result = await supabase.From<Country>()
_10
.Select(x => new object[] { x.Name, x.CountryId })
_10
.Where(x => x.Name != "Paris")
_10
.Get();


Match at least one filter

Finds all rows satisfying at least one of the filters.


_10
var result = await supabase.From<Country>()
_10
.Where(x => x.Id == 20 || x.Id == 30)
_10
.Get();


Using modifiers

Filters work on the row level—they allow you to return rows that only match certain conditions without changing the shape of the rows. Modifiers are everything that don't fit that definition—allowing you to change the format of the response (e.g., setting a limit or offset).


Order the results

Orders the result with the specified column.


_10
var result = await supabase.From<City>()
_10
.Select(x => new object[] { x.Name, x.CountryId })
_10
.Order(x => x.Id, Ordering.Descending)
_10
.Get();


Limit the number of rows returned

Limits the result with the specified count.


_10
var result = await supabase.From<City>()
_10
.Select(x => new object[] { x.Name, x.CountryId })
_10
.Limit(10)
_10
.Get();


Limit the query to a range

Limits the result to rows within the specified range, inclusive.


_10
var result = await supabase.From<City>()
_10
.Select("name, country_id")
_10
.Range(0, 3)
_10
.Get();


Retrieve one row of data

Retrieves only one row from the result. Result must be one row (e.g. using limit), otherwise this will result in an error.


_10
var result = await supabase.From<City>()
_10
.Select(x => new object[] { x.Name, x.CountryId })
_10
.Single();


Create a new user

Creates a new user.

  • By default, the user needs to verify their email address before logging in. To turn this off, disable Confirm email in your project.
  • Confirm email determines if users need to confirm their email address after signing up.
    • If Confirm email is enabled, a user is returned but session is null.
    • If Confirm email is disabled, both a user and a session are returned.
  • When the user confirms their email address, they are redirected to the SITE_URL by default. You can modify your SITE_URL or add additional redirect URLs in your project.
  • If SignUp() is called for an existing confirmed user:
    • When both Confirm email and Confirm phone (even when phone provider is disabled) are enabled in your project, an obfuscated/fake user object is returned.
    • When either Confirm email or Confirm phone (even when phone provider is disabled) is disabled, the error message, User already registered is returned.

_10
var session = await supabase.Auth.SignUp(email, password);


Listen to auth events

Receive a notification every time an auth event happens.

  • Types of auth events: AuthState.SignedIn, AuthState.SignedOut, AuthState.UserUpdated, AuthState.PasswordRecovery, AuthState.TokenRefreshed

_16
supabase.Auth.AddStateChangedListener((sender, changed) =>
_16
{
_16
switch (changed)
_16
{
_16
case AuthState.SignedIn:
_16
break;
_16
case AuthState.SignedOut:
_16
break;
_16
case AuthState.UserUpdated:
_16
break;
_16
case AuthState.PasswordRecovery:
_16
break;
_16
case AuthState.TokenRefreshed:
_16
break;
_16
}
_16
});


Sign in a user

Log in an existing user using email or phone number with password.

  • Requires either an email and password or a phone number and password.

_10
var session = await supabase.Auth.SignIn(email, password);


Sign in a user through OTP

  • Requires either an email or phone number.
  • This method is used for passwordless sign-ins where a OTP is sent to the user's email or phone number.
  • If you're using an email, you can configure whether you want the user to receive a magiclink or a OTP.
  • If you're using phone, you can configure whether you want the user to receive a OTP.
  • The magic link's destination URL is determined by the SITE_URL. You can modify the SITE_URL or add additional redirect urls in your project.

_10
var options = new SignInOptions { RedirectTo = "http://myredirect.example" };
_10
var didSendMagicLink = await supabase.Auth.SendMagicLink("joseph@supabase.io", options);


Sign in a user through OAuth

Signs the user in using third party OAuth providers.

  • This method is used for signing in using a third-party provider.
  • Supabase supports many different third-party providers.

_10
var signInUrl = supabase.Auth.SignIn(Provider.Github);


Sign out a user

Signs out the current user, if there is a logged in user.

  • In order to use the SignOut() method, the user needs to be signed in first.

_10
await supabase.Auth.SignOut();


Verify and log in through OTP

  • The VerifyOtp method takes in different verification types. If a phone number is used, the type can either be sms or phone_change. If an email address is used, the type can be one of the following: signup, magiclink, recovery, invite or email_change.
  • The verification type used should be determined based on the corresponding auth method called before VerifyOtp to sign up / sign-in a user.

_10
var session = await supabase.Auth.VerifyOTP("+13334445555", TOKEN, MobileOtpType.SMS);


Retrieve a session

Returns the session data, if there is an active session.


_10
var session = supabase.Auth.CurrentSession;


Retrieve a user

Returns the user data, if there is a logged in user.


_10
var user = supabase.Auth.CurrentUser;


Update a user

Updates user data, if there is a logged in user.

  • In order to use the UpdateUser() method, the user needs to be signed in first.
  • By Default, email updates sends a confirmation link to both the user's current and new email. To only send a confirmation link to the user's new email, disable Secure email change in your project's email auth provider settings.

_10
var attrs = new UserAttributes { Email = "new-email@example.com" };
_10
var response = await supabase.Auth.Update(attrs);


Invokes a Supabase Edge Function.

Invokes a Supabase Function. See the guide for details on writing Functions.

  • Requires an Authorization header.
  • Invoke params generally match the Fetch API spec.

_10
var options = new InvokeFunctionOptions
_10
{
_10
Headers = new Dictionary<string, string> {{ "Authorization", "Bearer 1234" }},
_10
Body = new Dictionary<string, object> { { "foo", "bar" } }
_10
};
_10
_10
await supabase.Functions.Invoke("hello", options: options);


Subscribe to channel

Subscribe to realtime changes in your database.

  • Realtime is disabled by default for new Projects for better database performance and security. You can turn it on by managing replication.
  • If you want to receive the "previous" data for updates and deletes, you will need to set REPLICA IDENTITY to FULL, like this: ALTER TABLE your_table REPLICA IDENTITY FULL;

_20
class CursorBroadcast : BaseBroadcast
_20
{
_20
[JsonProperty("cursorX")]
_20
public int CursorX {get; set;}
_20
_20
[JsonProperty("cursorY")]
_20
public int CursorY {get; set;}
_20
}
_20
_20
var channel = supabase.Realtime.Channel("any");
_20
var broadcast = channel.Register<CursorBroadcast>();
_20
broadcast.AddBroadcastEventHandler((sender, baseBroadcast) =>
_20
{
_20
var response = broadcast.Current();
_20
});
_20
_20
await channel.Subscribe();
_20
_20
// Send a broadcast
_20
await broadcast.Send("cursor", new CursorBroadcast { CursorX = 123, CursorY = 456 });


Unsubscribe from a channel

Unsubscribes and removes Realtime channel from Realtime client.

  • Removing a channel is a great way to maintain the performance of your project's Realtime service as well as your database if you're listening to Postgres changes. Supabase will automatically handle cleanup 30 seconds after a client is disconnected, but unused channels may cause degradation as more clients are simultaneously subscribed.

_10
var channel = await supabase.From<City>().On(ChannelEventType.All, (sender, change) => { });
_10
channel.Unsubscribe();
_10
_10
// OR
_10
_10
var channel = supabase.Realtime.Channel("realtime", "public", "*");
_10
channel.Unsubscribe()


Retrieve all channels

Returns all Realtime channels.


_10
var channels = supabase.Realtime.Subscriptions;


Create a bucket

Creates a new Storage bucket

  • Policy permissions required:
    • buckets permissions: insert
    • objects permissions: none

_10
var bucket = await supabase.Storage.CreateBucket("avatars");


Retrieve a bucket

Retrieves the details of an existing Storage bucket.

  • Policy permissions required:
    • buckets permissions: select
    • objects permissions: none

_10
var bucket = await supabase.Storage.GetBucket("avatars");


List all buckets

Retrieves the details of all Storage buckets within an existing product.

  • Policy permissions required:
    • buckets permissions: select
    • objects permissions: none

_10
var buckets = await supabase.Storage.ListBuckets();


Update a bucket

Updates a new Storage bucket

  • Policy permissions required:
    • buckets permissions: update
    • objects permissions: none

_10
var bucket = await supabase.Storage.UpdateBucket("avatars", new BucketUpsertOptions { Public = false });


Delete a bucket

Deletes an existing bucket. A bucket can't be deleted with existing objects inside it. You must first empty() the bucket.

  • Policy permissions required:
    • buckets permissions: select and delete
    • objects permissions: none

_10
var result = await supabase.Storage.DeleteBucket("avatars");


Empty a bucket

Removes all objects inside a single bucket.

  • Policy permissions required:
    • buckets permissions: select
    • objects permissions: select and delete

_10
var bucket = await supabase.Storage.EmptyBucket("avatars");


Upload a file

Uploads a file to an existing bucket.

  • Policy permissions required:
    • buckets permissions: none
    • objects permissions: insert

_10
var imagePath = Path.Combine("Assets", "fancy-avatar.png");
_10
_10
await supabase.Storage
_10
.From("avatars")
_10
.Upload(imagePath, "fancy-avatar.png", new FileOptions { CacheControl = "3600", Upsert = false });


Download a file

Downloads a file.

  • Policy permissions required:
    • buckets permissions: none
    • objects permissions: select

_10
var bytes = await supabase.Storage.From("avatars").Download("public/fancy-avatar.png");


List all files in a bucket

Lists all the files within a bucket.

  • Policy permissions required:
    • buckets permissions: none
    • objects permissions: select

_10
var objects = await supabase.Storage.From("avatars").List();


Replace an existing file

Replaces an existing file at the specified path with a new one.

  • Policy permissions required:
    • buckets permissions: none
    • objects permissions: update and select

_10
var imagePath = Path.Combine("Assets", "fancy-avatar.png");
_10
await supabase.Storage.From("avatars").Update(imagePath, "fancy-avatar.png");


Move an existing file

Moves an existing file, optionally renaming it at the same time.

  • Policy permissions required:
    • buckets permissions: none
    • objects permissions: update and select

_10
await supabase.Storage.From("avatars")
_10
.Move("public/fancy-avatar.png", "private/fancy-avatar.png");


Delete files in a bucket

Deletes files within the same bucket

  • Policy permissions required:
    • buckets permissions: none
    • objects permissions: delete and select

_10
await supabase.Storage.From("avatars").Remove(new List<string> { "public/fancy-avatar.png" });


Create a signed URL

Create signed url to download file without requiring permissions. This URL can be valid for a set number of seconds.

  • Policy permissions required:
    • buckets permissions: none
    • objects permissions: select

_10
var url = await supabase.Storage.From("avatars").CreateSignedUrl("public/fancy-avatar.png", 60);


Retrieve public URL

Retrieve URLs for assets in public buckets

  • The bucket needs to be set to public, either via UpdateBucket() or by going to Storage on supabase.com/dashboard, clicking the overflow menu on a bucket and choosing "Make public"
  • Policy permissions required:
    • buckets permissions: none
    • objects permissions: none

_10
var publicUrl = supabase.Storage.From("avatars").GetPublicUrl("public/fancy-avatar.png");


Release Notes

0.16.2 - 2024-04-02

  • Update dependency: gotrue-csharp@4.2.7
    • #88 Implement signInAnonymously from the JS client
    • Include additional 3rd party providers in constants.

0.16.1 - 2024-03-15

  • Update dependency: postgrest-csharp@3.5.1
    • Re: #147 - Supports Rpc specifying a generic type for its return.

0.16.0 - 2024-03-12

  • Update dependency: postgrest-csharp@3.5.0
    • Re: #78, Generalize query filtering creation in Table so that it matches new generic signatures.
    • Move from QueryFilter parameters to a more generic IPosgrestQueryFilter to support constructing new QueryFilters from a LINQ expression.
      • Note: Lists of QueryFilters will now need to be defined as: new List<IPostgrestQueryFilter> { new QueryFilter(), ... }
    • Adjust serialization of timestamps within a QueryFilter to support DateTime and DateTimeOffset using the ISO-8601 (https://stackoverflow.com/a/115002)
  • Update dependency: functions-csharp@1.3.2
    • Re: #5 Add support for specifying Http Timeout on a function call by adding HttpTimeout to InvokeFunctionOptions

0.15.0 - 2024-01-08

  • Update Dependency: gotrue-csharp@4.2.6
    • #83 Replaces JWTDecoder package with System.IdentityModel.Tokens.Jwt. Thanks @FantasyTeddy!
  • Update Dependency: postgrest-csharp@3.4.1
    • Re: #85 Fixes problem when using multiple .Order() methods by merging #86. Thanks @hunsra!
    • Re: #81
      • [Minor] Removes IgnoreOnInsertand IgnoreOnUpdate from ReferenceAttribute as changing these properties to false does not currently provide the expected functionality.
      • Fixes Insert and Update not working on models that have Reference specified on a property with a non-null value.

0.14.0 - 2023-12-15

  • Update Dependency: gotrue-csharp@4.2.5
    • #82 - Implements #82 - Creates a GenerateLink method on the AdminClient that supports signup, invite, magiclink, recovery, email_change_new and email_change_current
    • #81 - Adds InviteUserByEmailOptions as a parameter to the Gotrue Admin Client
  • Update Dependency: postgrest-csharp@3.3.0
    • Re: #78 Updates signatures for Not and Filter to include generic types for a better development experience.
    • Updates internal generic type names to be more descriptive.
    • Add support for LINQ predicates on Table<TModel>.Not() signatures

0.13.7 - 2023-11-13

  • Update Dependency: postgrest-csharp@3.2.10
    • Re: #76 Removes the incorrect ToUniversalTime conversion in the LINQ Where parser.

0.13.6 - 2023-10-12

  • Update Dependency: gotrue-csharp@4.2.3
    • Re: #80 Fixes Session.Expires() not being calculated correctly. Thanks @dayjay!

0.13.5 - 2023-10-09

  • Update Dependency: postgrest-csharp@3.2.9
    • Re: supabase-csharp#115 Additional support for a model referencing another model with multiple foreign keys.
    • Re: supabase-csharp#115 Adds support for multiple references attached to the same model (foreign keys) on a single C# Model.

0.13.4 - 2023-10-08

  • Update Dependency: gotrue-csharp@4.2.2
    • Re: #78 - Implements PKCE flow support for ResetPasswordForEmail.

0.13.3 - 2023-09-15

  • Re: #107 - removes Realtime socket being disconnected on a User sign-out - only the subscriptions should be removed.

0.13.2 - 2023-09-15

  • Update dependency: postgrest-csharp@3.2.7
    • Implements a TableWithCache for Get requests that can pull reactive Models from cache before making a remote request.
    • Re: supabase-csharp#85 Includes sourcelink support.
    • Re: #75 Fix issue with marshalling of stored procedure arguments. Big thank you to @corrideat!

0.13.1 - 2023-08-26

  • Update dependency: supabase-storage-csharp@1.4.0
    • Fixes #11 - Which implements missing SupabaseStorageException on failure status codes for Upload, Download, Move, CreateSignedUrl and CreateSignedUrls.

0.13.0 - 2023-08-26

  • Update dependency: gotrue-csharp@4.2.1
    • #74 - Fixes bug where token refresh interval was not honored by client. Thanks @slater1!
    • Minor Breaking changes: #72 - Fixes Calling SetAuth does not actually set Authorization Headers for subsequent requests by implementing SetSession
      • Removes RefreshToken(string refreshToken) and SetAuth(string accessToken in favor of SetSession(string accessToken, string refreshToken)
      • Makes RefreshAccessToken require accessToken and refreshToken as parameters - overrides the authorization headers to use the supplied token
      • Migrates project internal times to use DateTime.UtcNow over DateTime.Now.

0.12.2 - 2023-07-28

  • Update dependency: realtime-csharp@6.0.4
    • Fixes #29 Where the Realtime client could disconnect from channels after a few hours and fail to reconnect by removing the case where the IsSubscribe flag is flipped when encountering a channel error.
  • Update dependency: postgrest-csharp@3.2.5
    • Re: supabase-community/supabase-csharp#81: Clarifies ReferenceAttribute by changing shouldFilterTopLevel to useInnerJoin and adds an additional constructor for ReferenceAttribute with a shortcut for specifying the JoinType

0.12.1 - 2023-06-29

  • Update dependency: gotrue-csharp@4.1.1
    • #68 Changes Network Status to use the interface instead of client
  • Update dependency: postgrest-csharp@3.2.4
    • #70 Minor Unity related fixes

0.12.0 - 2023-06-25

  • Update dependency: gotrue-csharp@4.1.0
    • Minor #66 - Separates out Admin JWT functionality into a separate AdminClient
    • #67 - Adds shutdown method which terminates the background refresh threads.
    • Movement of much of the documentation for methods out of their classes and into their interfaces.
    • Language features locked to C#9
  • Update dependency: postgrest-csharp@3.2.3
    • #69 Locks language version to C#9
    • #68 Makes RPC parameters optional

Thanks @wiverson for the work in this release!

0.11.1 - 2023-06-10

  • Update dependencies: functions-csharp@1.3.1, gotrue-csharp@4.0.4, postgrest-csharp@3.2.2, realtime-csharp@6.0.3, supabase-storage-csharp@1.3.2, supabase-core@0.0.3
    • Namespaces assembly names to make them unique among other dependencies, i.e: Core.dll becomes Supabase.Core.dll which will hopefully prevent future collisions.

0.11.0 - 2023-05-24

  • Update dependency: postgrest-csharp@3.2.0
    • General codebase and QOL improvements. Exceptions are generally thrown through PostgrestException now instead of Exception. A FailureHint.Reason is provided with failures if possible to parse.
    • AddDebugListener is now available on the client to help with debugging
    • Merges #65 Cleanup + Add better exception handling
    • Merges #66 Local test Fixes
    • Fixes #67 Postgrest Reference attribute is producing StackOverflow for circular references
  • Update dependency: gotrue-csharp@4.0.2
    • #58 - Add support for the reauthentication endpoint which allows for secure password changes.
  • Update dependency: realtime-csharp@6.0.1
    • Updates publishing action for future packages, includes README and icon.
    • Merges #28 and #30
    • The realtime client now takes a "fail-fast" approach. On establishing an initial connection, client will throw a RealtimeException in ConnectAsync() if the socket server is unreachable. After an initial connection has been established, the client will continue attempting reconnections indefinitely until disconnected.
    • [Major, New] C# EventHandlers have been changed to delegates. This should allow for cleaner event data access over the previous subclassed EventArgs setup. Events are scoped accordingly. For example, the RealtimeSocket error handlers will receive events regarding socket connectivity; whereas the RealtimeChannel error handlers will receive events according to Channel joining/leaving/etc. This is implemented with the following methods prefixed by ( Add/Remove/Clear):
      • RealtimeBroadcast.AddBroadcastEventHandler
      • RealtimePresence.AddPresenceEventHandler
      • RealtimeSocket.AddStateChangedHandler
      • RealtimeSocket.AddMessageReceivedHandler
      • RealtimeSocket.AddHeartbeatHandler
      • RealtimeSocket.AddErrorHandler
      • RealtimeClient.AddDebugHandler
      • RealtimeClient.AddStateChangedHandler
      • RealtimeChannel.AddPostgresChangeHandler
      • RealtimeChannel.AddMessageReceivedHandler
      • RealtimeChannel.AddErrorHandler
      • Push.AddMessageReceivedHandler
    • [Major, new] ClientOptions.Logger has been removed in favor of Client.AddDebugHandler() which allows for implementing custom logging solutions if desired.
      • A simple logger can be set up with the following:

      _10
      client.AddDebugHandler((sender, message, exception) => Debug.WriteLine(message));

    • [Major] Connect() has been marked Obsolete in favor of ConnectAsync()
    • Custom reconnection logic has been removed in favor of using the built-in logic from Websocket.Client@4.6.1.
    • Exceptions that are handled within this library have been marked as RealtimeExceptions.
    • The local, docker-composed test suite has been brought back (as opposed to remotely testing on live supabase servers) to test against.
    • Comments have been added throughout the entire codebase and an XML file is now generated on build.

0.10.0 - 2023-05-14

  • Changes options to require Supabase.SupabaseOptions.SessionPersistor from using ISupabaseSessionHandler to IGotrueSessionPersistance<Session> (these are now synchronous operations).
  • Update dependency: gotrue-csharp@4.0.1
    • #60 - Add interfaces, bug fixes, additional error reason detection. Thanks @wiverson!
    • #57 Refactor exceptions, code cleanup, and move to delegate auth state changes
      • Huge thank you to @wiverson for his help on this refactor and release!
      • Changes
        • Exceptions have been simplified to a single GotrueException. A Reason field has been added to GotrueException to clarify what happened. This should also be easier to manage as the Gotrue server API & messages evolve.
        • The session delegates for Save/Load/Destroy have been simplified to no longer require async.
        • Console logging in a few places (most notable the background refresh thread) has been removed in favor of a notification method. See Client.AddDebugListener() and the test cases for examples. This will allow you to implement your own logging strategy (write to temp file, console, user visible err console, etc).
        • The client now more reliably emits AuthState changes.
        • There is now a single source of truth for headers in the stateful Client - the Options headers.
      • New feature:
        • Added a Settings request to the stateless API only - you can now query the server instance to determine if it's got the settings you need. This might allow for things like a visual component in a tool to verify the GoTrue settings are working correctly, or tests that run differently depending on the server configuration.
      • Implementation notes:
        • Test cases have been added to help ensure reliability of auth state change notifications and persistence.
        • Persistence is now managed via the same notifications as auth state change

0.9.1 - 2023-04-28

  • Update dependency: gotrue-csharp@3.1.1
    • Implements SignInWithIdToken for Apple/Google signing from LW7. A HUGE thank you to @wiverson!
  • Update dependency: realtime-csharp@5.0.5
    • Re: #27 PostgresChangesOptions was not setting listenType in constructor. Thanks @Kuffs2205
  • Update dependency: supabase-storage-csharp@1.2.10
    • Re: #7 Implements a DownloadPublicFile method.

0.9.0 - 2023-04-12

  • Update dependency: gotrue-csharp@3.1.0

    • [Minor] Implements PKCE auth flow. SignIn using a provider now returns an instance of ProviderAuthState rather than a string.
  • Update dependency: supabase-storage-csharp@1.2.9

    • Implements storage features from LW7:

0.8.8 - 2023-03-29

  • Update dependency: gotrue-csharp@3.0.6
    • Supports adding SignInOptions (i.e. RedirectTo) on OAuth Provider SignIn requests.

0.8.7 - 2023-03-23

  • Update dependency: realtime-csharp@5.0.4
    • Re: #26 - Fixes Connect() not returning callback result when the socket isn't null. Thanks @BlueWaterCrystal!

0.8.6 - 2023-03-23

  • Update dependency: supabase-storage-csharp@1.2.8

0.8.5 - 2023-03-10

  • Update dependency: realtime-csharp@5.0.3
    • Re: #25 - Support Channel being resubscribed after having been unsubscribed, fixes rejoin timer being erroneously called on channel Unsubscribe. Thanks @Kuffs2205!

0.8.4 - 2023-03-03

  • Update dependency: supabase-storage-csharp@1.2.7
    • Re: #4 Implementation for ClientOptions which supports specifying Upload, Download, and Request timeouts.
  • Update dependency: realtime-csharp@5.0.2
    • Re: #24 - Fixes join failing until reconnect happened + adds access token push on channel join. Big thank you to @Honeyhead for the help debugging and identifying!

0.8.3 - 2023-02-26

  • Update dependency: supabase-storage-csharp@1.2.5
  • Update dependency: gotrue-csharp@3.0.5
    • Fixes #44 - refresh timer should automatically reattempt (interval of 5s) for HTTP exceptions - gracefully exits on invalid refresh and triggers an AuthState.Changed event

0.8.2 - 2023-02-26

  • Update dependency: supabase-storage-csharp@1.2.4
    • UploadOrUpdate now appropriately throws request exceptions

0.8.1 - 2023-02-06

  • Update dependency: realtime-csharp@5.0.1
    • Re: #22 - SerializerSettings were not being passed to PostgresChangesResponse - Thanks @Shenrak for the help debugging!

0.8.0 - 2023-01-31

  • Update dependency: realtime-csharp@5.0.0
    • Re: #21 Provide API for presence, broadcast and postgres_changes
      • [Major, New] Channel.PostgresChanges event will receive the wildcard * changes event, not Channel.OnMessage.
      • [Major] Channel.OnInsert, Channel.OnUpdate, and Channel.OnDelete now conform to the server's payload of Response.Payload.**Data**
      • [Major] Channel.OnInsert, Channel.OnUpdate, and Channel.OnDelete now return PostgresChangesEventArgs
      • [Minor] Rename Channel to RealtimeChannel
      • Supports better handling of disconnects in RealtimeSocket and adds a Client.OnReconnect event.
      • [Minor] Moves ChannelOptions to Channel.ChannelOptions
      • [Minor] Moves ChannelStateChangedEventArgs to Channel.ChannelStateChangedEventArgs
      • [Minor] Moves Push to Channel.Push
      • [Minor] Moves Channel.ChannelState to Constants.ChannelState
      • [Minor] Moves SocketResponse, SocketRequest, SocketResponsePayload, SocketResponseEventArgs, and SocketStateChangedEventArgs to Socket namespace.
      • [New] Adds RealtimeBroadcast
      • [New] Adds RealtimePresence
      • [Improvement] Better handling of disconnection/reconnection
  • Update dependency: postgrest-csharp@3.1.3
    • Another fix for #61 which futher typechecks nullable values.

0.7.2 - 2023-01-27

  • Update dependency: gotrue-csharp@3.0.4
    • Makes Session.CreatedAt a publicly settable property, which should fix incorrect dates on retrieved Sessions.
  • Update dependency: postgrest-csharp@3.1.2
    • Fix #61 which did not correctly parse Linq Where when encountering a nullable type.
    • Add missing support for transforming for == null and != null

0.7.1 - 2023-01-17

  • Update dependency: postgrest-csharp@3.1.1
    • Fix issue from supabase-community/supabase-csharp#48 where boolean model properties would not be evaluated in predicate expressions

0.7.0 - 2023-01-16

  • Update dependency: postgrest-csharp@3.1.0
    • [Minor] Breaking API Change: PrimaryKey attribute defaults to shouldInsert: false as most uses will have the Database generate the primary key.
    • Merged #60 which Added linq support for Select, Where, OnConflict, Columns, Order, Update, Set, and Delete

0.6.2 - 2022-11-22

  • Update dependency: postgrest-csharp@3.0.4
    • GetHeaders is now passed to ModeledResponse and BaseModel so that the default Update and Delete methods use the latest credentials
    • GetHeaders is used in Rpc calls (re: #39)

0.6.1 - 2022-11-12

  • [Hotfix] GetHeaders was not passing properly to SupabaseTable and Gotrue.Api

0.6.0 - 2022-11-12

[BREAKING CHANGES]

  • Client is no longer a singleton, singleton interactions (if desired) are left to the developer to implement.
  • Client supports injection of dependent clients after initialization via property:
    • Auth
    • Functions
    • Realtime
    • Postgrest
    • Storage
  • SupabaseModel contains no logic but remains for backwards compatibility. (Marked Obsolete)
  • ClientOptions.ShouldInitializeRealtime was removed (no longer auto initialized)
  • ClientOptions now references an ISupabaseSessionHandler which specifies expected functionality for session persistence on Gotrue (replaces ClientOptions.SessionPersistor, ClientOptions.SessionRetriever, and ClientOptions.SessionDestroyer).
  • supabase-csharp and all child libraries now have support nullity

Other Changes:

  • Update dependency: functions-csharp@1.2.1
  • Update dependency: gotrue-csharp@3.0.2
  • Update dependency: postgrest-csharp@3.0.2
  • Update dependency: realtime-csharp@4.0.1
  • Update dependency: supabase-storage-csharp@1.2.3
  • Update dependency: supabase-core@0.0.2

Big thank you to @veleek for his insight into these changes.

Re: #35, #34, #23, #36

0.5.3 - 2022-10-11

  • Update dependency: postgrest-csharp@2.1.0
    • [Minor] Breaking API change: Remove BaseModel.PrimaryKeyValue and BaseModel.PrimaryKeyColumn in favor of a PrimaryKey dictionary with support for composite keys.
    • Re: #48 - Add support for derived models on ReferenceAttribute
    • Re: #49 - Added Match(T model)

0.5.2 - 2022-9-13

  • Update dependency: postgrest-csharp@2.0.12
    • Merged #47 which added cancellation token support to Table<T> methods. Thanks @devpikachu!

0.5.1 - 2022-8-1

  • Update dependency: postgrest-csharp@2.0.11
  • Update dependency: supabase-storage-csharp@1.1.1

0.5.0 - 2022-7-17

  • Update dependency: postgrest-csharp@2.0.9
  • Update dependency: realtime-csharp@3.0.1
  • Update dependency: supabase-storage-csharp@1.1.0
    • API Change [Breaking/Minor] Library no longer uses WebClient and instead leverages HttpClient. Progress events on Upload and Download are now handled with EventHandler<float> instead of WebClient EventHandlers.

0.4.4 - 2022-5-24

  • Update dependency: gotrue-csharp@2.4.5
  • Update dependency: postgrest-csharp@2.0.8

0.4.3 - 2022-5-13

  • Update dependency: gotrue-csharp@2.4.4

0.4.2 - 2022-4-30

  • Update dependency: gotrue-csharp@2.4.3

0.4.1 - 2022-4-23

  • Update dependency: gotrue-csharp@2.4.2

0.4.0 - 2022-4-12

  • Add support for functions-csharp@1.0.1, giving access to invoking Supabase's edge functions.
  • Update dependency: gotrue-csharp@2.4.1

0.3.5 - 2022-4-11

  • Update dependency: postgres-csharp@2.0.7

0.3.4 - 2022-03-28

  • Update dependency: gotrue-csharp@2.4.0

0.3.3 - 2022-02-27

  • Update dependency: gotrue-csharp@2.3.6
  • Update dependency: supabase-storage-csharp@1.0.2

0.3.2 - 2022-02-18

0.3.1 - 2022-01-20

  • Update dependency: gotrue-csharp@2.3.5
    • #23 Added redirect_url option for MagicLink sign in (Thanks @MisterJimson)
    • #21 Added SignOut method to Stateless Client ( Thanks @fplaras)

0.3.0 - 2021-12-30

  • Update dependency: postgrest-csharp@2.0.6
    • Add support for NullValueHandling to be specified on a Column Attribute and for it to be honored on Inserts and Updates. Defaults to: NullValueHandling.Include.
      • Implements #38
  • Update dependency: realtime-csharp@2.0.8
    • Implement Upstream Realtime RLS Error Broadcast Handler
      • Implements #12
    • SocketResponse now exposes a method: OldModel, that hydrates the OldRecord property into a model.

0.2.12 - 2021-12-29

  • Update dependency: gotrue-csharp@2.3.3
    • SignUp will return a Session with a populated User object on an unconfirmed signup.
      • Fixes #19
      • Developers who were using a null check on Session.User will need to adjust accordingly.
  • Update dependency: postgrest-csharp@2.0.5
    • Fix for #37 - Return Type minimal would fail to resolve because of incorrect Accept headers. Added header and test to verify for future.
    • Fix for #36 - Inserting/Upserting bulk records would fail while doing an unnecessary generic coercion.

0.2.11 - 2021-12-24

  • Update dependency: gotrue-csharp@2.3.2 (changes CreateUser parameters to conform to AdminUserAttributes)
  • Update dependency: realtime-csharp@2.0.7

0.2.10 - 2021-12-23

  • Update dependency: gotrue-csharp@2.3.0 (adds metadata support for user signup, see #14)

0.2.9 - 2021-12-9

  • Separate Storage client from Supabase repo and into storage-csharp, supabase-csharp now references new repo.

0.2.8 - 2021-12-4

  • Update gotrue-csharp to 2.2.4
    • Adds support for ListUsers (paginate, sort, filter), GetUserById, CreateUser, and UpdateById

0.2.7 - 2021-12-2

  • Update gotrue-csharp to 2.2.3
    • Adds support for sending password resets to users.

0.2.6 - 2021-11-29

  • Support for #12
  • Update realtime-csharp to 2.0.6
  • Update gotrue-csharp to 2.2.2
  • Add StatelessClient re:#7