bitrave / azure-mobile-services-for-unity3d

A suite of Azure Mobile Services plugins for Unity3D, cross platform with common interfaces, with examples
Other
67 stars 34 forks source link

No response #9

Closed Bungalow12 closed 10 years ago

Bungalow12 commented 10 years ago

Hi, I recently decided to begin using Unity for projects and intended to hook up these games to my own service using azure. On Azure I had created a database and some stored procedures and then an Azure MobileService. Using the azure mobile service I had no problem receiving the data. Of course then it occurred to me the mobile services would not work on Unity and came across this awesome project.

However I am never getting data back from the function calls. I'm hoping I am just doing something odd in the way I am trying to wait for the callback to occur.

One note to make is this project is specifically a windows metro project not using unity as essentially a proof of concept test bed. but including the rest sharp and BitRave.Azure DLLs as references.

My example function is:

//Get User's misc data
public IEnumerable<UserData> GetUserMiscData(int userId)
        {
            IEnumerable<UserData> userData = null;
            bool callComplete = false;
            OnlineServices.MobileService.Where<UserData>(p => p.ID == userId, azureResponse =>
                {
                    if (azureResponse.Status == AzureResponseStatus.Success)
                    {
                        userData = azureResponse.ResponseData;                        
                    }
                    callComplete = true;
                });

            //Wait for the call to complete.
            while (!callComplete) ;
            return userData;
        }

With the loop this waits forever. Without the loop it finishes immediately returning nothing. Any advice on getting started would be amazing.

Bungalow12 commented 10 years ago

Well I still see the same issues now that I am using Unity and adding all the files for the service from the universal folder. I am never getting a reply. Any thoughts?

rtargosz commented 10 years ago

I assume you've looked at the example code? I wound up going another direction last week due to various issues with JSON .NET and Unity (I'm using App42 cloud now), but had this working pretty well on some platforms two weeks ago. I was using callbacks, but you can use delegates just as well I think. (App42 uses a separate class for their callbacks, making delegates untenable; when I tried the Azure code I left my callbacks in place).

Depending on your configuration/authentication setup, you may need to log in first, something like this: void Login() { var _azure = new AzureMobileServices(AzureEndPoint, ApplicationKey); _azure.LoginAsync(AuthenticationProvider.Facebook, FacebookAccessToken, LoginAsyncCallback); }

private static void LoginAsyncCallback(AzureResponse response) { if (response.Status == AzureResponseStatus.Success) _azure.User = response.ResponseData; else Debug.Log("Error:" + response.StatusCode); }

I only ever had this working with the RestSharp DLLs provided in the sample Universal project. I was never able to get RestSharp building and working from code. This, combined with some incompatibilities in JSON .NET for Unity drove me away from Azure for my current project since I want to ship it in a few days!

vaughanknight commented 10 years ago

Apologies for the lack of replies. I've been flat out with other work. I'll have a look at this in the next few days. Also, I need to work out the best way to include the RestSharp source code.

On Wed, Mar 19, 2014 at 11:11 AM, Rob Targosz notifications@github.comwrote:

I assume you've looked at the example code? I wound up going another direction last week due to various issues with JSON .NET and Unity (I'm using App42 cloud now), but had this working pretty well on some platforms two weeks ago. I was using callbacks, but you can use delegates just as well I think. (App42 uses a separate class for their callbacks, making delegates untenable; when I tried the Azure code I left my callbacks in place).

Depending on your configuration/authentication setup, you may need to log in first, something like this: void Login() { var _azure = new AzureMobileServices(AzureEndPoint, ApplicationKey); _azure.LoginAsync(AuthenticationProvider.Facebook, FacebookAccessToken, LoginAsyncCallback); }

private static void LoginAsyncCallback(AzureResponse response) { if (response.Status == AzureResponseStatus.Success) _azure.User = response.ResponseData; else Debug.Log("Error:" + response.StatusCode); }

I only ever had this working with the RestSharp DLLs provided in the sample Universal project. I was never able to get RestSharp building and working from code. This, combined with some incompatibilities in JSON .NET for Unity drove me away from Azure for my current project since I want to ship it in a few days!

Reply to this email directly or view it on GitHubhttps://github.com/bitrave/azure-mobile-services-for-unity3d/issues/9#issuecomment-38004667 .

Bungalow12 commented 10 years ago

No worries Vaughanknight. Once this works my life is much easier. I guess I'm confused. My Azure DB consists currently of User with an ID and UserMiscData where each row is UserID, Key, & Value. I made sure all of my code names match exactly with the DB entries as I thought the Expression Writer would have searched for a table with typename and member. No such luck. :( My callback is never hit. Thanks for the info rtargosz. Moving off of azure isn't an option for me. :( Am I required to login to a service like facebook? I didn't intend for the requirement of a third party account. The only code I have beside the above is the connection url and code to my azure DB. I'm in no rush but the sooner the better as this is supposed to be my whole leaderboard, achievements, matchmaking, and multiplayer back end. :/

Thanks!

Bungalow12 commented 10 years ago

A little more of my investigation leads that the expression writer is failing on my predicate in the call to Where. The expression writer is determining that the NodeType is "The requested type has been unloaded" or something to that likeness. Therefore my request that is given to the RestRequest constructor is null. I'm not sure I'll have time to look deeper into the expression writer issue but if I do I'll be sure to update here.

Bungalow12 commented 10 years ago

Scratch that. I performed a more thorough step through to determine the final query passed to RestRequest is "UserMiscData?$filter=UserID eq 1" which would be correct. So either it is within the RestSharp source code or something does not like my lambda. In this case I am going to attempt using a method call and see if that behaves any better.

UPDATE: using a callback method did not work either. No response after a 5 second timeout.

Bungalow12 commented 10 years ago

Well even though my Azure DB has a table named UserMiscData we are not finding it according to rest: Rest Response:{"code":404,"error":"Error: Table 'UserMiscData' does not exist."} Would the schema be necessary 'b12Online.UserMiscData'? If so how would I ensure this? Below is an image of my table on Azure table

vaughanknight commented 10 years ago

Just verifying you have set up the Azure Mobile Service? That's the important bit, the actuals behind that should be hidden from the client app.

On Thu, Mar 20, 2014 at 5:27 AM, Bungalow12 notifications@github.comwrote:

Well even though my Azure DB has a table named UserMiscData we are not finding it according to rest: Rest Response:{"code":404,"error":"Error: Table 'UserMiscData' does not exist."} Would the schema be necessary 'b12Online.UserMiscData'? If so how would I ensure this? Below is an image of my table on Azure [image: table]https://f.cloud.github.com/assets/2235941/2464199/fe434f14-af93-11e3-97b3-b623b28a1435.png

Reply to this email directly or view it on GitHubhttps://github.com/bitrave/azure-mobile-services-for-unity3d/issues/9#issuecomment-38088638 .

Bungalow12 commented 10 years ago

Yes I have created a mobile service. That has one API call for GetUserMiscData taking the ID. This calls the stored procedure in my DB with the same purpose. Before moving to your Azure Mobile Services for Unity 3D I had tested my DB and service out on a very basic Windows 8 app and it received the data just fine. I'm wondering if I am going about the workflow with this library correctly. First, in my unity object start I create a new instance of my online services class which has a static member for the AzureMobileService. Next, I call my GetUserMiscData method posted earlier. I since added a 5 second timeout to the while loop. Even though it is just basic proof of concept code I hate locking up the thread ;). It is after the timeout finishes I'll see the logging appear within Unity that RestRequest hit a 404.

The azure mobile services gives two keys. Should I be using the master key for these specific libraries?

I've tried rewriting the whole example as completely callback based removing the blocking while and also rewrite the lambda in my GetUserMiscData method as a separate function. None of these approaches worked. I hope that information will be useful. Thanks for looking at this.

vaughanknight commented 10 years ago

Can you share the lines of code that create the service/invoke the service? It's going to be something simple.

On Fri, Mar 21, 2014 at 3:32 AM, Bungalow12 notifications@github.comwrote:

Yes I have created a mobile service. That has one API call for GetUserMiscData taking the ID. This calls the stored procedure in my DB with the same purpose. Before moving to your Azure Mobile Services for Unity 3D I had tested my DB and service out on a very basic Windows 8 app and it received the data just fine. I'm wondering if I am going about the workflow with this library correctly. First, in my unity object start I create a new instance of my online services class which has a static member for the AzureMobileService. Next, I call my GetUserMiscData method posted earlier. I since added a 5 second timeout to the while loop. Even though it is just basic proof of concept code I hate locking up the thread ;). It is after the timeout finishes I'll see the logging appear within Unity that RestRequest hit a 404.

The azure mobile services gives two keys. Should I be using the master key for these specific libraries?

I've tried rewriting the whole example as completely callback based removing the blocking while and also rewrite the lambda in my GetUserMiscData method as a separate function. None of these approaches worked. I hope that information will be useful. Thanks for looking at this.

Reply to this email directly or view it on GitHubhttps://github.com/bitrave/azure-mobile-services-for-unity3d/issues/9#issuecomment-38189415 .

Bungalow12 commented 10 years ago

Absolutely Test.cs - MonoBehavior Object:

using UnityEngine;
using System.Collections;
using B12Online;
using System.Collections.Generic;

public class Test : MonoBehaviour {
    B12OnlineServices b12Online;
    // Use this for initialization
    void Start () {
        b12Online = new B12OnlineServices();
        var userMiscData = this.b12Online.GetUserMiscData(1);
        int i = 10 + 5;
        i++;
    }

    // Update is called once per frame
    void Update () {

    }
}

B12OnlineServces.cs:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Bitrave.Azure;

namespace B12Online
{
    public class B12OnlineServices
    {
        private static readonly TimeSpan Timeout = TimeSpan.FromSeconds (5);

        internal static AzureMobileServices MobileService = new AzureMobileServices(
            "https://b12online.azure-mobile.net/",
            "TrustMeThisIsRightButRemoved");

        public IEnumerable<UserMiscData> GetUserMiscData(int userId)
        {
            IEnumerable<UserMiscData> userData = null;
            DateTime requestTime = DateTime.Now;
            bool callComplete = false;
            B12OnlineServices.MobileService.Where<UserMiscData>(p => p.UserID == userId, azureResponse =>
                {
                    if (azureResponse.Status == AzureResponseStatus.Success)
                    {
                        userData = azureResponse.ResponseData;
                    }
                    callComplete = true;
                });

            //Wait for the call to complete or to time out.
            while (!callComplete && (DateTime.Now - requestTime) < B12OnlineServices.Timeout) ;
            return userData;
        }
    }
}

UserMiscData.cs:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Newtonsoft.Json;

namespace B12Online
{
    public class UserMiscData
    {
        [JsonProperty(PropertyName = "UserID")]
        internal int UserID { get; set; }

        [JsonProperty(PropertyName = "key")]
        public string Key { get; set;}

        [JsonProperty(PropertyName = "value")]
        public string Value { get; set; }
    }
}
vaughanknight commented 10 years ago

You shouldn't need a while loop. That method should return immediately, with the callback being invoked asynchronously. You don't return userData, you handle it in the callback.

Event happens-> Invoke Azure Mobile Services with callback method Callback happens-> Callback method is invoked, does what it needs to do

GetUserMiscData shouldn't return a value, or have a while loop, that's just going to hang the thread while it waits for a response.

On Fri, Mar 21, 2014 at 11:01 AM, Bungalow12 notifications@github.comwrote:

Absolutely Test.cs - MonoBehavior Object:

using UnityEngine;using System.Collections;using B12Online;using System.Collections.Generic; public class Test : MonoBehaviour { B12OnlineServices b12Online; // Use this for initialization void Start () { b12Online = new B12OnlineServices(); var userMiscData = this.b12Online.GetUserMiscData(1); int i = 10 + 5; i++; }

// Update is called once per frame
void Update () {

}}

B12OnlineServces.cs:

using System;using System.Collections.Generic;using System.Linq;using System.Text;using Bitrave.Azure; namespace B12Online{ public class B12OnlineServices { private static readonly TimeSpan Timeout = TimeSpan.FromSeconds (5);

    internal static AzureMobileServices MobileService = new AzureMobileServices(
        "https://b12online.azure-mobile.net/",
        "TrustMeThisIsRightButRemoved");

    public IEnumerable<UserMiscData> GetUserMiscData(int userId)
    {
        IEnumerable<UserMiscData> userData = null;
        DateTime requestTime = DateTime.Now;
        bool callComplete = false;
        B12OnlineServices.MobileService.Where<UserMiscData>(p => p.UserID == userId, azureResponse =>

            {
                if (azureResponse.Status == AzureResponseStatus.Success)
                {
                    userData = azureResponse.ResponseData;
                }
                callComplete = true;
            });

        //Wait for the call to complete or to time out.
        while (!callComplete && (DateTime.Now - requestTime) < B12OnlineServices.Timeout) ;
        return userData;
    }
}}

UserMiscData.cs:

using System;using System.Collections.Generic;using System.Linq;using System.Text;using Newtonsoft.Json; namespace B12Online{ public class UserMiscData { [JsonProperty(PropertyName = "UserID")] internal int UserID { get; set; } [JsonProperty(PropertyName = "key")] public string Key { get; set;} [JsonProperty(PropertyName = "value")] public string Value { get; set; } }}

Reply to this email directly or view it on GitHubhttps://github.com/bitrave/azure-mobile-services-for-unity3d/issues/9#issuecomment-38235351 .

Bungalow12 commented 10 years ago

I have that exact implementation elsewhere which I tried. Let me find that and post it.

Bungalow12 commented 10 years ago

The version handling things without attempting to block does not work either. At least I don't get a 404 message from Rest though. Unless of course MonoDevelop sucks at hitting breakpoints in callbacks or events.

Test.cs:

using UnityEngine;
using System.Collections;
using B12Online;
using System.Collections.Generic;

public class Test : MonoBehaviour {
    B12OnlineServices b12Online;
    // Use this for initialization
    void Start () {
        b12Online = new B12OnlineServices();
        b12Online.OnUserMiscDataReceived += UserMiscData;
        this.b12Online.GetUserMiscData(1);        
    }

    void UserMiscData(IEnumerable<UserMiscData> userMiscData)
    {
        int i = 10 + 5;
        i++;
    }

    // Update is called once per frame
    void Update () {

    }
}

B12OnlineServies.cs:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Bitrave.Azure;

namespace B12Online
{
    public class B12OnlineServices
    {
        private static readonly TimeSpan Timeout = TimeSpan.FromSeconds (5);

        internal static AzureMobileServices MobileService = new AzureMobileServices(
            "https://b12online.azure-mobile.net/",
            "RemovedAsBefore");

        public event UserMiscDataReceived OnUserMiscDataReceived;

        public void GetUserMiscData(int userId)
        {
            B12OnlineServices.MobileService.Where<UserMiscData>(p => p.UserID == userId, GetUserMiscDataCallback);
        }

        private void GetUserMiscDataCallback(AzureResponse<List<UserMiscData>> azureResponse)
        {
            if (azureResponse.Status == AzureResponseStatus.Success)
            {
                if (this.OnUserMiscDataReceived != null)
                {
                    this.OnUserMiscDataReceived(azureResponse.ResponseData);
                }
            }
        }
        public delegate void UserMiscDataReceived(IEnumerable<UserMiscData> userMiscData);
    }
}
Bungalow12 commented 10 years ago

I want to be sure I have everything set up Azure side correctly for this. I have:

Does this code require a Service Bus or Cloud Services?

vaughanknight commented 10 years ago

It shouldn't.

Just confirming that your test results are from inside the editor? On PC or Mac?

On Tue, Mar 25, 2014 at 4:23 AM, Bungalow12 notifications@github.comwrote:

I want to be sure I have everything set up Azure side correctly for this. I have:

  • SQL Database
  • Mobile Services using the above database. (Azure libraries work)

Does this code require a Service Bus or Cloud Services?

Reply to this email directly or view it on GitHubhttps://github.com/bitrave/azure-mobile-services-for-unity3d/issues/9#issuecomment-38473551 .

Bungalow12 commented 10 years ago

Inside the editor on PC. I'd also run under a debugger with breakpoints in the callbacks using MonoDevelop.

vaughanknight commented 10 years ago

Great. Just making sure we're under the same environment.

On Tue, Mar 25, 2014 at 9:58 AM, Bungalow12 notifications@github.comwrote:

Inside the editor on PC. I'd also run under a debugger with breakpoints in the callbacks using MonoDevelop.

Reply to this email directly or view it on GitHubhttps://github.com/bitrave/azure-mobile-services-for-unity3d/issues/9#issuecomment-38512159 .

Bungalow12 commented 10 years ago

I also have one functionality question. Does this library directly query the table? Also is there a way to call a stored procedure?

vaughanknight commented 10 years ago

The library calls the Azure Mobile Service, so it supports server side queries. It doesn't support store procedures yet. We'll be adding that, and to do that you would use a custom Azure Mobile Service, and call that, which in turn would call your stored procedure.

On Wed, Mar 26, 2014 at 9:29 AM, Bungalow12 notifications@github.comwrote:

I also have one functionality question. Does this library directly query the table? Also is there a way to call a stored procedure?

Reply to this email directly or view it on GitHubhttps://github.com/bitrave/azure-mobile-services-for-unity3d/issues/9#issuecomment-38629546 .

eivholt commented 10 years ago

A few things to check: Unless it has recently been changed this API assumes you have old Azure Mobile endpoints where the generated Id-fields of each table is of type int. I seem to remember I experienced similar behavior when querying the new string(guid)-Id tables. From your database table you seem to have int-Id but maybe you can share the definition of the corresponding Azure table? Also the API does not support JsonObject.Name on classes, so your class has to have the exact same name as the Azure resource(not necessarily the sql table name if you made the sql table first). I am not sure about JsonProperty.PropertyName. Any entry in the Azure Mobile Services log? Maybe put a console.log(..) as the first Read codeline?

Bungalow12 commented 10 years ago

Hi Eivholt. Provided is the linked table for UserMiscData usertable My mobile Service is reporting no log. I know I had successfully connected a while back using the official azure mobile service apis accessing my API associated with my sproc. I'm not sure if this clears overtime however I just tried again and have nothing listed in the logs. If the table name is not necessarily he class name how do I determine the Azure resource name? As for the console.log do you mean within the AzureMobileServices code prior to the RestRequest?

eivholt commented 10 years ago

This is the picture of your sql table posted earlier. Your Azure client does not know about this and I suggest you inspect the generated endpoint (rest resource) for UserMiscData. You will find this in the azure managment portal looking like this http://thebitchwhocodes.com/wp-content/uploads/2014/02/azure-mobile-services-step9.jpg It might be worth using the exact same names (casing included) as class and for properties on your business objects as the names you find in the definition as the Azure client supplied by microsoft seems to be more tolerant of mismatching casing and usage of JsonObject- and JsonProperty-attributes. At least I have had to make some changes because of this.

Are you able to view the "read" JavaScript of the REST service for the sql table UserMiscData? It should look something like this:http://andriyadi.me/wp-content/uploads/2013/03/Screen-Shot-2013-03-03-at-5.17.11-AM.png I recomend you put a console.log("Read script of UserMiscData was run!"); as the first line of code inside this function and see if the log gets any entries. It looks something like this: https://public.dm2302.livefilestore.com/y2pB7oQc2vNNv8Pbak0ibFk5yjy6_RV81TPQx5WflnERMsQsgXAfvmlkRAwEbExj7j2Do9k9TjmQy7gAct7X-dVytK4zxBPfOAI5WCh29-fVJI/image27.png?psid=1&rdrts=70659129

If you are having trouble finding any of these screens I suggest going through some more tutorials.

Bungalow12 commented 10 years ago

No I just feel foolish. My understanding was that it auto linked these together. I just began adding the data. I'm sorry. I'm close now but maybe you are aware of what this error means. "Invalid column name 'id'. If you contact a support representative please include this correlation identifier: " I get this when trying to browser the UserMiscData item. The UserMiscData.UserID index is linked to User.ID as can be seen from my SQL table images of both above. Below is the Service Data stuff for User and UserMiscData. I'm really new to this so perhaps something is wrong with my keys in my table. usermiscdataservicedat usermiscdatatabledata

The UserMiscData gives this error on browse: error

I'm not entirely sure what that could mean. :/

Bungalow12 commented 10 years ago

Well I'll be damned that is now just an error within the browser interface on Azure. The actual code of mine works now!

Bungalow12 commented 10 years ago

So to sum up my issue the code was not necessarily the problem. The problem however was that I never added the Tables to the Data tab within Azure Mobile Services. Stupid mistake and a huge timewaster based on my lack of understanding. Note to self research tutorials first! Thank you all for the input and time put into this.

eivholt commented 10 years ago

I'm glad you worked this out! You have no idea how many mistakes I have made learning azure :) Having figured most things out it kicks ass, tho!

vaughanknight commented 10 years ago

Super excited you guys collaborated on this. Thanks heaps eivholt.

On Sat, Mar 29, 2014 at 9:40 AM, eivholt notifications@github.com wrote:

I'm glad you worked this out! You have no idea how many mistakes I have made learning azure :) Having figured most things out it kicks ass, tho!

Reply to this email directly or view it on GitHubhttps://github.com/bitrave/azure-mobile-services-for-unity3d/issues/9#issuecomment-38975610 .

Bungalow12 commented 10 years ago

Hey guys. I didn't realize I can reopen although this new issue #11 is different I believe one of you might have a quick answer since my data is getting from azure to rest. I anticipate stepping through the azure mobile service at minimum tonight to try and find where the data is being lost.