Обновление документа в Firebase Firestore из. Net Базового консольного приложения - PullRequest
0 голосов
/ 17 января 2020

Вариант использования

Angular Приложение Firebase, которое использует Firestore в качестве формы постоянства, необходимо для связи с ботом Discord. Я построил бот-синхронизатор для посредничества между существующим внешним ботом и веб-приложением. Достаточно информации для поиска и обновления документа.

Проблема

Обновление не происходит из-за проблемы с преобразованием.
Исключение: Unable to create converter for type Models.Participant

Вопрос

Попробовав несколько решений, в основном использующих преобразование json, я упростил код, чтобы получить / получить более высокую оценку asp ситуации. Я предполагаю, что чего-то очевидного не хватает, но из-за моей неопытности с пожарной базой (firestore) я не могу понять, что на этом этапе.

public async Task<bool> NextTurn(string encounterName)
{
    var encounterSnapshotQuery = await _encountersCollection.WhereEqualTo("name", encounterName).GetSnapshotAsync();

    foreach (DocumentSnapshot encounterSnapshot in encounterSnapshotQuery.Documents)
    {
        Dictionary<string, object> data = encounterSnapshot.ToDictionary();
        var name = data["name"].ToString();

        if (name == encounterName)
        {
            var participants = data["participants"].ToParticipants();
            var orderedParticipants = participants.OrderByDescending(x => x.initiative + x.roll).ToList();

            var current = orderedParticipants.Single(x => x.isCurrent != null && x.isCurrent is bool && (bool)x.isCurrent);
            var currentIndex = orderedParticipants.FindIndex(x => x.characterName == current.characterName);
            var next = orderedParticipants[currentIndex + 1];

            current.hasPlayedThisTurn = true;
            current.isCurrent = false;
            next.isCurrent = true;

            var updates = new Dictionary<FieldPath, object>
            {
                { new FieldPath("participants"),  orderedParticipants }
            };

            try
            {
                await encounterSnapshot.Reference.UpdateAsync(updates);
            }
            catch (Exception ex)
            {
                _logger.LogError(new EventId(), ex, "Update failed.");
            }
        }

    }

    return true;
}

Если есть очевидные ошибки в подходах, также приветствуются предложения.

Обновление

Полное сообщение об исключении:

 at Google.Cloud.Firestore.Converters.ConverterCache.CreateConverter(Type targetType)
   at Google.Cloud.Firestore.Converters.ConverterCache.<>c.<GetConverter>b__1_0(Type t)
   at System.Collections.Concurrent.ConcurrentDictionary`2.GetOrAdd(TKey key, Func`2 valueFactory)
   at Google.Cloud.Firestore.Converters.ConverterCache.GetConverter(Type targetType)
   at Google.Cloud.Firestore.SerializationContext.GetConverter(Type targetType)
   at Google.Cloud.Firestore.ValueSerializer.Serialize(SerializationContext context, Object value)
   at Google.Cloud.Firestore.Converters.ListConverterBase.Serialize(SerializationContext context, Object value)
   at Google.Cloud.Firestore.ValueSerializer.Serialize(SerializationContext context, Object value)
   at Google.Cloud.Firestore.WriteBatch.<>c__DisplayClass12_0.<Update>b__1(KeyValuePair`2 pair)
   at System.Linq.Enumerable.ToDictionary[TSource,TKey,TElement](IEnumerable`1 source, Func`2 keySelector, Func`2 elementSelector, IEqualityComparer`1 comparer)
   at System.Linq.Enumerable.ToDictionary[TSource,TKey,TElement](IEnumerable`1 source, Func`2 keySelector, Func`2 elementSelector)
   at Google.Cloud.Firestore.WriteBatch.Update(DocumentReference documentReference, IDictionary`2 updates, Precondition precondition)
   at Google.Cloud.Firestore.DocumentReference.UpdateAsync(IDictionary`2 updates, Precondition precondition, CancellationToken cancellationToken)

Модель участника

public class Participant
{
    public string playerName { get; set; }
    public int experience { get; set; }
    public int level { get; set; }
    public string characterName { get; set; }
    public string playerUid { get; set; }
    public object joined { get; set; }
    public string type { get; set; }
    public object abilities { get; set; }
    public int roll { get; set; }
    public bool? isCurrent { get; set; }
    public int sizeModifier { get; set; }
    public int initiative { get; set; }
    public bool? hasPlayedThisTurn { get; set; }
    public string portraitUrl { get; set; }
}

Интерфейс машинописи участника, используемый для создания модель в магазине

export interface Participant {
    playerName: string,
    characterName: string,
    initiative: number,
    roll: number,
    playerUid: string,
    joined: Date,
    portraitUrl: string,
    level: number,
    experience: number,
    isCurrent: boolean,
    sizeModifier: number,
    type: string,
    abilities: {
        strength: number,
        dexterity: number,
        constitution: number,
        intelligence: number,
        wisdom: number,
        charisma: number
    },
    hasPlayedThisTurn: boolean
}

Обратите внимание, что я поиграл с изменением модели C#, чтобы попытаться это исправить. Это текущее состояние. Сообщение было одинаковым независимо от того, какие изменения я внес.

1 Ответ

2 голосов
/ 18 января 2020

Вот два решения:

1) Вы должны украсить класс с помощью

[FirestoreData]
public class Participant
{
    [FirestoreProperty]
    public string playerName { get; set; }

    [FirestoreProperty("playerExperience")] //you can give the properties custom names as well
    public int experience { get; set; }

    //so on
    public int level { get; set; }
    public string characterName { get; set; }
    public string playerUid { get; set; }
    public object joined { get; set; }
    public string type { get; set; }
    public object abilities { get; set; }
    public int roll { get; set; }
    public bool? isCurrent { get; set; }
    public int sizeModifier { get; set; }
    public int initiative { get; set; }
    public bool? hasPlayedThisTurn { get; set; }
    public string portraitUrl { get; set; }
}

или (Отказ от ответственности, может быть более чистый способ сделать это)

путем преобразования участника в ExpandoObject ExpandoObject https://docs.microsoft.com/en-us/dotnet/api/system.dynamic.expandoobject

с использованием Newtonsoft. Json

или решение, не требующее Newtonsoft. Json представляется как хорошо: Как преобразовать любой C# объект в ExpandoObject?

var serializedParticipant = JsonConvert.SerializeObject(participant);
var deserializedParticipant = JsonConvert.DeserializeObject<ExpandoObject>(serializedParticipant);

, а затем обновить Firestore с вашими участниками как ExpandoObject вместо Model.Participant

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...