Как опубликовать список C # в базе данных Firebase в реальном времени?

#c# #.net #firebase #firebase-realtime-database #json.net

#c# #.net #firebase #firebase-realtime-database #json.net

Вопрос:

Я создаю простое приложение для карточной игры, в которое можно играть онлайн с друзьями, которые присоединяются к игре с помощью случайно сгенерированного кода.

Я решил структурировать свою базу данных следующим образом.

 {
  "GameRooms" : {
    "-MF23P_AMI--leAoWfh5" : {
      "Code" : "s1a5a2",
      "NumberOfSpoons" : 1,
      "Players" : {
        "-MF23Tz3c00FCkGgKeUy" : {
          "Name" : "player1"
        }
      }
    }
  }
}
  

Я использую FirebaseDatabase.Пакет Net NuGet для взаимодействия с базой данных. Я могу добавить 1 игрока в игру под Players узлом, однако после этого я не могу добавлять других игроков, которые присоединяются с помощью кода.

Это код, в котором я создаю игру под GameRooms узлом ( firebase это мой объект FirebaseClient):

 public async Task CreateRoomAsync(Game game, Player gameCreator)
{
    var gameSerialized = JsonConvert.SerializeObject(game, Formatting.None);
    await firebase.Child("GameRooms").PostAsync(gameSerialized);
    JoinRoomAsync(game.Code, gameCreator);
}
  

Это проблемный код, который должен поместить проигрыватель под Players узел. (Это работает только в первый раз.):

 public async void JoinRoomAsync(string gameCode, Player newPlayer)
{
    string gameKey = "Error";
    try
    {
        // FirebaseException thrown at this line of code.
        gameKey = (await firebase.Child("GameRooms").OnceAsync<Game>()).Where(a => a.Object.Code == gameCode).FirstOrDefault().Key;

    }
    catch (FirebaseException e)
    {
        var innerException = e.InnerException.Message;
    }      

    await firebase.Child("GameRooms").Child(gameKey).Child("Players").PostAsync(newPlayer);

}
  

Внутреннее исключение FirebaseException:

 Cannot deserialize the current JSON object (e.g. {"name":"value"}) into type 
'System.Collections.Generic.List`1[Spoons.Models.Player]' 
because the type requires a JSON array (e.g. [1,2,3]) to deserialize correctly.
To fix this error either change the JSON to a JSON array (e.g. [1,2,3]) or change 
the deserialized type so that it is a normal .NET type (e.g. not a primitive type like integer, 
not a collection type like an array or List<T>) that can be deserialized from a JSON object. 
JsonObjectAttribute can also be added to the type to force it to deserialize from a JSON object.
Path '-MEesAsT1nVWPSxzbf8a.Players.0', line 1, position 75.
  

Я пытался выяснить, как правильно загрузить список C # в базу данных Firebase Realtime.

Это классы Game и Player :

 public class Game
    {
        int numberOfSpoons = 1;

        public string Code { get; set; }
        public int NumberOfSpoons { get { return numberOfSpoons; } set { numberOfSpoons = value; } }

        Deck deck = new Deck();

        public Deck GameDeck 
        {
            get { return deck; }
            set { deck = value; } 
        }

        public List<Player> Players { get; set; } = new List<Player>();

        public Game(string gameCode) 
        {
            this.Code = gameCode;
        }
  
     public class Player
    {
        public string Name { get; set; }

        public Player(string name) 
        {
            this.Name = name;
        }
    }
  

Я некоторое время работал над исправлением этого, но у меня ничего не получилось. Я был бы очень признателен за любую помощь или предложения о том, как я могу преодолеть это. Дайте мне знать, если вам понадобится дополнительная информация.

Комментарии:

1. Итак, ошибка действительно полезна, не так ли? Чтобы исправить эту ошибку, либо измените JSON на массив JSON (например, [1,2,3]), либо измените десериализованный тип, чтобы он был обычным . Тип NET (например, не примитивный тип, такой как integer, не тип коллекции, такой как array или List<T>), который может быть десериализован из объекта JSON. Атрибут JsonObjectAttribute также может быть добавлен к типу, чтобы заставить его десериализоваться из объекта JSON.

2. @CoolBots Я понял ошибку, я просто не уверен в том, как я буду вносить изменения в свой код.

3. Является ли эта строка в вашем JSON: "-MF23Tz3c00FCkGgKeUy" каким-то идентификатором? Генерируется ли он динамически?

4. @CoolBots Да, он динамически генерируется firebase при размещении объекта в базе данных.

5. @CoolBots Это также ключ, который используется для доступа к содержимому под этим узлом при извлечении данных.

Ответ №1:

Вам нужен тип оболочки — ваш JSON точно не является List<Player> . Я могу успешно десериализовать ваши данные JSON, если я использую следующую оболочку вместо List<Player> :

 public class PlayerCollection
{
    public Dictionary<string, Player> Players { get; set; }
}
  

Причиной этого является структура JSON:

 "Players" : {
        "-MF23Tz3c00FCkGgKeUy" : {
          "Name" : "player1"
        }
    }
  

Players Здесь верхний уровень — это корневой объект, в моем случае PlayerCollection . Однако то, что находится внутри, по-прежнему не является List<Player> — существует автоматически сгенерированный ID — так что это скорее Dictionary<string, Player> — где string это идентификатор, а { "Name" : "player1" } это Player объект.

Итак, вернемся к ошибке, которую вы получаете — я предоставляю обычное .Тип NET (например, не примитивный тип, такой как integer, не тип коллекции, такой как array или List), который может быть десериализован из объекта JSON.

Комментарии:

1. В этом есть большой смысл. Я собираюсь попробовать это. Большое спасибо за ваш ответ!

2. только что попробовал это и работает отлично. Большое спасибо!

3. @HarshDave потрясающе! Рад, что смог помочь!