Closed kaushalkumar86 closed 7 months ago
What client stack are you using? Unity? MAUI?
Unity, developing android app, tested on Samsung S9+
On Fri, 11 Aug, 2023, 4:57 am Will Iverson, @.***> wrote:
What client stack are you using? Unity? MAUI?
— Reply to this email directly, view it on GitHub https://github.com/supabase-community/realtime-csharp/issues/34#issuecomment-1674048635, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABG2A547RUJTIFASMGGJSJ3XUVU4ZANCNFSM6AAAAAA3LONKXA . You are receiving this because you authored the thread.Message ID: @.***>
Try moving the debug line up so it's the very first thing being called, and don't put anything else but that debug line in for the moment. Want to double-check there's nothing else wonky that's affecting the object.
Got it working, seems like some network issue, change my WiFi network and it works fine now, even on that same network also.
On Fri, 11 Aug, 2023, 10:03 pm Will Iverson, @.***> wrote:
Try moving the debug line up so it's the very first thing being called, and don't put anything else but that debug line in for the moment. Want to double-check there's nothing else wonky that's affecting the object.
— Reply to this email directly, view it on GitHub https://github.com/supabase-community/realtime-csharp/issues/34#issuecomment-1675065611, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABG2A54K2ZCRCAIPKBK6ULTXUZNGPANCNFSM6AAAAAA3LONKXA . You are receiving this because you authored the thread.Message ID: @.***>
Excellent. FYI I added a Network Status class for GoTrue auth, but I haven't looked at applying any of that to Realtime. That would be something Very Cool to add but I haven't had reason to do it yet. Right now I'm focused on shipping my Unity project and for that I use Auth/GoTrue and RPC heavily but not Realtime.
In the meantime you could try using that class and the networks state listeners to update the realtime subscriptions. e.g. drop and resubscribe if the network goes away.
Thanks, I'll check it out. Please mark it as closed.
On Sat, 12 Aug, 2023, 11:18 pm Will Iverson, @.***> wrote:
Excellent. FYI I added a Network Status class for GoTrue auth, but I haven't looked at applying any of that to Realtime. That would be something Very Cool to add but I haven't had reason to do it yet. Right now I'm focused on shipping my Unity project and for that I use Auth/GoTrue and RPC heavily but not Realtime.
In the meantime you could try using that class and the networks state listeners to update the realtime subscriptions. e.g. drop and resubscribe if the network goes away.
— Reply to this email directly, view it on GitHub https://github.com/supabase-community/realtime-csharp/issues/34#issuecomment-1676028187, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABG2A525EE7DJBXJ363ZEVTXU66XTANCNFSM6AAAAAA3LONKXA . You are receiving this because you authored the thread.Message ID: @.***>
Glad it's working!
I'm going to leave adding network status checking to realtime as an enhancement for now, if that's ok.
@wiverson is supabase c# now compatible with unity? last time i tried it was not and i`m using the apis directly
I can speak to Auth and RPC working great. I literally just posted my apps this week, note that they include native Sign in with Apple talking back to Supabase auth...
I'm planning on writing up notes soon. Make sure you use UniTask for async/await, the Unity provided Newtonsoft JSON.
I am using supabase-C sharp. Using Google auth and its working fine, wanted to use Facebook login but it seems it requires webview.
Postgrest is working awesome, just as u wanted.
Had a couple of hiccups due to network issues in Realtime, but no fault of package.
I am using it for a new multi-player android game I am working on.
On Sun, 13 Aug, 2023, 1:37 pm dungeon2567, @.***> wrote:
@wiverson https://github.com/wiverson is supabase c# now compatible with unity? last time i tried it was not and i`m using the apis directly
— Reply to this email directly, view it on GitHub https://github.com/supabase-community/realtime-csharp/issues/34#issuecomment-1676274247, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABG2A53H7HX6JIHEE53FFPDXVCDNBANCNFSM6AAAAAA3LONKXA . You are receiving this because you authored the thread.Message ID: @.***>
@kaushalkumar86 Which lib are you using for the Google sign in? I've used this Simple Google Sign-In in the past.
Also, did you get it working with nonces?
I am using https://github.com/googlesamples/google-signin-unity package for Google signing, this gives me id token, which I then pass to supabase signin to activate session. Same steps as used in firebase auth. I can share my code file if u need, its very simple.
On Mon, 14 Aug, 2023, 3:11 am Will Iverson, @.***> wrote:
@kaushalkumar86 https://github.com/kaushalkumar86 Which lib are you using for the Google sign in? I've used this Simple Google Sign-In https://assetstore.unity.com/packages/tools/integration/simple-google-sign-in-250663 in the past.
Also, did you get it working with nonces?
— Reply to this email directly, view it on GitHub https://github.com/supabase-community/realtime-csharp/issues/34#issuecomment-1676469842, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABG2A52PD5UBH7YMBYRZWV3XVFC2HANCNFSM6AAAAAA3LONKXA . You are receiving this because you were mentioned.Message ID: @.***>
@wiverson Alternatively, u can also check https://docs.unity.com/ugs/en-us/manual/authentication/manual/platform-signin-google , u just need the IDToken after Google Signin to pass it to Supabase auth...
I think I figured out the issue. This behavior of postgrest changes listening only once was caused because I was changing some texts (UI changes) as soon as I got and update. Moved those UI changes to update function (UI thread) and it seems to work fine now. Anyhow, the listener is not on UI thread and I was updating UI
Hello again, I found a couple of issues with NetworkStatus class. I checked on android.
I had to go through a conventional way. created a class which calls a link at an interval of say 4 secs in loop. If the response is ok, we have internet and it resubscribe the realtime listener, else it shows network not available.
Hmm. FWIW here is the Unity script I'm using to initialize things. I'm building & testing on iOS mainly right now, Apple Watch right now, Android is next. It's possible that there is something about the init sequence and/or the interaction with the UI thread is borking stuff up.
Might want to try breaking into pieces eg just see if you can get the NetworkChange stuff to work alone.
Hi, I checked your code, u might be getting it to work on Apple or other devices, but its not working on Android.
What I did is, made a NetworkHandler class as per below:-
public class NetworkHandler : MonoBehaviour
{
public static NetworkHandler manager;
private bool checkerIsActive = false;
private Action<NetworkStatus> networkListener = null;
private NetworkStatus currStatus = NetworkStatus.None;
private void Awake()
{
manager = this;
}
public void SetNetworkListener(Action<NetworkStatus> listener)
{
networkListener = listener;
}
public async void StartNetChecker(string url)
{
checkerIsActive = true;
await PingCheck(url);
}
private void SetInternetAccess(NetworkStatus isOnline)
{
if (currStatus != isOnline)
{
currStatus = isOnline;
networkListener?.Invoke(currStatus);
}
}
public async Task PingCheck(string url)
{
while (checkerIsActive)
{
if (Application.internetReachability != NetworkReachability.NotReachable)
{
try
{
var reply = await new HttpClient().GetAsync(url);
if (reply?.StatusCode == System.Net.HttpStatusCode.OK)
{
SetInternetAccess(NetworkStatus.Online);
}
else
{
SetInternetAccess(NetworkStatus.Offline);
}
}
catch (Exception)
{
SetInternetAccess(NetworkStatus.Offline);
}
}
else
{
SetInternetAccess(NetworkStatus.Offline);
await Task.Delay(Preferences.oneSecinMilli);
}
await Task.Delay(Preferences.twoSecinMilli);
}
}
private void OnDestroy()
{
networkListener = null;
checkerIsActive = false;
}
public enum NetworkStatus
{
Online,
Offline,
None
}
/*public static void StartNetworkChecker() //If wanted to do as Coroutine
{
checkerIsActive = true;
if (NetworkChecker != null)
{
manager.StopCoroutine(NetworkChecker);
NetworkChecker = null;
}
NetworkChecker = InternetAccessCheck();
manager.StartCoroutine(NetworkChecker);
}
public static void StopNetworkChecker()
{
checkerIsActive = false;
if (NetworkChecker != null)
manager.StopCoroutine(NetworkChecker);
}
private static IEnumerator InternetAccessCheck()
{
MSG.Log(MSG.TAG, "Network Started");
while (checkerIsActive)
{
if (Application.internetReachability != NetworkReachability.NotReachable)
{
UnityWebRequest request = new UnityWebRequest("https://www.supabase.com/");
yield return request.SendWebRequest();
if (string.IsNullOrEmpty(request.error))
{
SetInternetAccess(true);
}
else
{
SetInternetAccess(false);
}
}
else
{
SetInternetAccess(false);
yield return new WaitForSeconds(2f);
}
yield return new WaitForSeconds(2f);
}
}*/}
And then from the SupabaseHandler class called an instance of this cass as:-
public void EnableListener()
{
NetworkHandler.manager.SetNetworkListener(NetworkListener);
NetworkHandler.manager.StartNetChecker(Preferences.stringPingUrl);
}
private async void EnablePostGrestListener(PlayerClass userSent)
{
try
{
databaseChannel = supabase.Realtime.Channel("public-users");
databaseChannel.Register(new PostgresChangesOptions(schema: "public", table: "Users", ListenType.Updates, $"userID=eq.{userSent.UserId}"));
databaseChannel.AddPostgresChangeHandler(ListenType.All, PostgresUpdatedHandler);
IRealtimeChannel cn = await databaseChannel.Subscribe();
}
catch (Exception e)
{
MSG.Log(MSG.TAG, e.Message);
}
}
private void PostgresUpdatedHandler(IRealtimeChannel _, PostgresChangesResponse change)
{
_Player.player = change.Model<SupaUsers.SupaPlayer>();
ispl?.OnPlayerStatusUpdate(_Player);
}
//END of Realtime-Postgrest
private void NetworkListener(NetworkStatus isNetworkAvailable)
{
if (isNetworkAvailable == NetworkStatus.Online)
{
if (databaseChannel != null)
{
databaseChannel.Unsubscribe();
databaseChannel = null;
}
EnablePostGrestListener(PlayerClass user);
}
else
{
MSG.Log(MSG.TAG, "No internet");
ispl?.OnErrorOccured(); //No internet
}
}
//ENd of Network-Scan
It will run a task which continuously checks for internet at an interval of 2 seconds.
https://github.com/supabase/realtime-js/issues/121 watching as potentially related
Hi again..
private async void EnablePostGrestListener(string userSent)
{
try
{
databaseChannel = supabase.Realtime.Channel("public-users");
databaseChannel.Register(new PostgresChangesOptions(schema: "public", table: "Users", ListenType.Updates, $"userID=eq.{userSent}"));
databaseChannel.AddPostgresChangeHandler(ListenType.Updates, PostgresUpdatedHandler);
//databaseChannel.AddMessageReceivedHandler(MessageReceivedHandler);
databaseChannel.AddStateChangedHandler(StateChangedHandler);
databaseChannel.AddErrorHandler(ErrorEventHandler);
IRealtimeChannel cn = await databaseChannel.Subscribe();
}
catch (Exception e)
{
MSG.Log(MSG.TAG, e.Message);
}
}
private void MessageReceivedHandler(IRealtimeChannel sender, SocketResponse message)
{
MSG.Log(MSG.TAG, "Message = " + message.Topic);
MSG.Log(MSG.TAG, "Message = " + message._event);
MSG.Log(MSG.TAG, "Message = " + message.Payload.Message);
MSG.Log(MSG.TAG, "Message = " + message.Payload.Status);
}
private void StateChangedHandler(IRealtimeChannel sender, Constants.ChannelState state)
{
MSG.Log(MSG.TAG, "State = " + state);
if(state == Constants.ChannelState.Joined)
{
//Internet available and connected
ispl?.OnGainInternet();
}
else if (state == Constants.ChannelState.Errored)
{
databaseChannel.Rejoin();
}
}
private void ErrorEventHandler(IRealtimeChannel sender, RealtimeException exception)
{
MSG.Log(MSG.TAG, "exception = " + exception.ToString());
}
private void PostgresUpdatedHandler(IRealtimeChannel _, PostgresChangesResponse change)
{
_Player.player = change.Model<SupaUsers.SupaPlayer>();
ispl?.OnPlayerStatusUpdate(_Player);
}
//END of Realtime-Postgrest
private void NetworkListener(NetworkStatus isNetworkAvailable)
{
if (isNetworkAvailable == NetworkStatus.Online)
{
if (databaseChannel != null)
{
databaseChannel.Rejoin();
}
else
{
EnablePostGrestListener(UserID);
}
}
else
{
ispl?.OnLostInternet(); //No internet
}
}
In my last update, I had no way of finding if Realtime listerner has been successfully implemented. SO, I added a few lines. The issue in this is it works sometimes and sometimes dont. The issue is with stateChangedhandler, initially the state passed is joining and after successful joining, the sate passed is joined, which is what is required and should do. But sometimes, statechangedhandler is not triggered even if the realtime listener has succesfully joined, moreover the bool value of IfisJoined remains false.
I also tried unsubscribing the channel and open it again, but it always returns with state == errored in statechangedhandler.
I am getting Push Timeout when it is errored. please guide me how should I proceed?
I'm looking in some of the Android stuff as I just started converting my project over (I started with iOS first). One extremely weird thing I found is that so long as my Unity code uses this API - Application.internetReachability somewhere in my project it appears to be generating different Android permissions in the generated Gradle project. I was getting some weird errors related to network connectivity and the .NET network status APIs that went away when I added a call to this in my code.
Very weird, not sure if has something to do with IL2CPP code stripping (which I have flipped on for both iOS and Android).
I checked my manifest file, it uses only internet permissions. and .Net network status APIs never worked for me in the first place, that is why I used Application.internetReachability. The issue with Realtime listeners not working when internet is reconnected was not solved, I tried
I could not understand as to why this is happening. Even closed and opened realtime sockets, but everytime statechangehandler was getting triggered with state error and error msg as push timeout. Finally when closed everything and reinitialized supabase.client, realtime's statechangehandler was getting triggers with state joined.
This is my updated code for realtime listeners and its working properly as it should.
private async void EnablePostGrestListener(Player userSent)
{
try
{
databaseChannel = supabase.Realtime.Channel("public-users");
databaseChannel.Register(new PostgresChangesOptions(schema: "public", table: "Users", ListenType.All, $"userID=eq.{userSent.UserId}"));
//databaseChannel = supabase.Realtime.Channel(database: "realtime", schema: "public", table: "Users", column: "userID", value: userSent.UserId);
databaseChannel.AddPostgresChangeHandler(ListenType.All, PostgresUpdatedHandler);
databaseChannel.AddStateChangedHandler(StateChangedHandler);
databaseChannel.AddErrorHandler(ErrorEventHandler);
IRealtimeChannel cn = await databaseChannel.Subscribe();
}
catch (Exception e)
{
MSG.Log(MSG.TAG, e.Message);
ReinitialiseSupabase(false);
}
}
private void StateChangedHandler(IRealtimeChannel sender, Constants.ChannelState state)
{
MSG.Log(MSG.TAG, "State = " + state);
if(state == Constants.ChannelState.Joined)
{
//Internet available and connected
ispl?.OnGainInternet();
}
else if (state == Constants.ChannelState.Errored)
{
ReinitialiseSupabase(false);
}
}
private void ErrorEventHandler(IRealtimeChannel sender, RealtimeException exception)
{
MSG.Log(MSG.TAG, "exception = " + exception.ToString());
}
private void PostgresUpdatedHandler(IRealtimeChannel _, PostgresChangesResponse change)
{
_Player.player = change.Model<SupaUsers.SupaPlayer>();
ispl?.OnPlayerStatusUpdate(_Player);
}
//END of Realtime-Postgrest and start of network supabase
private void ReinitialiseSupabase(bool supaInitialised)
{
if (supaInitialised)
{
NetworkListener(NetworkHandler.GetCurrStatus());
}
else
{
ShutSupabase();
InitializeSupa(ReinitialiseSupabase);
}
}
private void NetworkListener(NetworkStatus isNetworkAvailable)
{
if (isNetworkAvailable == NetworkStatus.Online)
{
if (supabase == null)
{
InitializeSupa(ReinitialiseSupabase);
}
else
{
EnablePostGrestListener(currPlayer);
}
}
else
{
ShutSupabase();
ispl?.OnLostInternet(); //No internet
}
}
When I update table, the listener is only getting called once. Do I need to enable listener everyting before making an update?