#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 потрясающе! Рад, что смог помочь!