8

Mam problem z ustaleniem sposobu sprawdzania danych stron trzecich. Oto jak to jest skonstruowaneC# Ścieżka zapytań dla danych Firebase za pośrednictwem FirebaseDatabase.net

/bucketa/bucketb/bucketc/someguidtypekey/anotherguidtypekey/(fields I want to map here)

Próbowałem to:

var stats = await firebase.Child("bucketa/bucketb/bucketc").OnceAsync<WrapperClass>(); 

Gdzie WrapperClass jest combo Key/przedmiot, to przedmiot jest inny kombi Klucz/Object, a następnie, że obiekt jest rzeczywisty klasa.

public class WrapperClass 
{ 
    public string Key { get; set; } 
    public WrapperClass2 Stats { get; set; } 
} 

public class WrapperClass2 
{ 
    public string Key { get; set; } 
    public RealClass Stats { get; set; } 
} 

public class RealClass 
{ 
    public string Field1 { get; set; } 
    public string Field2 { get; set; } 
    public string Field3 { get; set; } 
    public string Field4 { get; set; } 
} 

Próbowałem również:

var stats = await firebase.Child("bucketa/bucketb/bucketc/*/*").OnceAsync<RealClass>(); 

Ale to właśnie wrócił ciąg typu obiektu.

Czy ktoś może pomóc tutaj?

Jest to C#, używając FirebaseDatabase.net

Edit:

Dobra, teraz jesteśmy coraz bliżej. Wdrożenie @ElmarJensen fix (z jednej ze swoich komentarzach):

...OnceAsync<Dictionary<string, Dictionary<string, RealClass>>>(); 

Jestem teraz otrzymuję błąd:

Error converting value True to type 'RealClass'

W błędu, to mówi, że próbuje przekonwertować RealClass.property1 gdzie property1 jest typu bool.

Dlaczego próbuje przekonwertować obiekt property1 na mój typ obiektu RealClass zamiast obiektu nadrzędnego? Struktura ma dla mnie sens. W wyjątku właściwość "responseData" zawiera wszystkie rekordy, których oczekiwałem w poprawnym formacie JSON, więc nie jestem pewien, co się tutaj dzieje.

Edit 2: Oto rzeczywisty format danych:

{ 
    "0M6bRFLLokR6sIJAcKFN6y91NXB3": { 
     "-KYdDf62eQUMGb-ov737": { 
      "somethingBoolean":true, 
      "asdf":"Joe User", 
      "oasdfasdfsad": { 
       "firstName":"asdf", 
       "lastName":"asdfasdf", 
       "tasdfme":"Wasdfh", 
       "teasdfore":6, 
       "teaasdfme":"SDFO" 
      }, 
      "fasdfewaef":0, 
      "startedAt":1.481381640492956E9, 
      "updatedAt":1.481381687802693E9, 
      "wfefeaefw":"182", 
      "asdf": { 
       "firstName":"asdf", 
       "lastName":"asdf", 
       "asdf":"asdfasdfasdf", 
       "teamScore":0, 
       "asefeawfawef":"DFDFSWEF" 
      }, 
      "aefawefawefawefawef":0 
     } 
    } 
} 
+0

Sprawdź to: [pobierania danych] (https://firebase.google.com/docs/database/admin/retrieve-data) –

Odpowiedz

2

symbole wieloznaczne ("bucketa/bucketb/bucketc/*/*") nie występują tak w Firebase, więc jeśli nie masz wpływ na strukturę danych, utknąłeś, pobierając jednocześnie pełne drzewo danych z katalogu głównego w "bucketa/bucketb/bucketc". Problem polega na tym, że dla bazy danych firebase-dotnet, "dzieci" tego drzewa (someguidtypekey/anotherguidtypekey) pojawią się jako właściwości obiektu z GUIDkey jako nazwą właściwości - co oznacza, że ​​musisz znać przyciski w czasie kompilacji aby to działało. Biorąc jednak pod uwagę, że metoda wykorzystuje JSON.net pod maską, i który obsługuje biblioteki deserializacji do słowników zamiast przedmiotów, jak również, co następuje może rzeczywiście działać:

await firebase.Child("bucketa/bucketb/bucketc").OnceAsync<Dictiona‌​ry<string, Dictionary<string, RealCl‌​ass>>>(); 

Ponadto, jeśli jest to tylko jedno zapytanie, to byłoby dość łatwo zrobić to "ręcznie" za pomocą HttpClient lub użyć FireSharp (innego FB.Biblioteka netto https://github.com/ziyasal/FireSharp), który umożliwia łatwy bezpośredni dostęp do „surowego” zwróciło JSON, podobnie jak to:

FirebaseResponse response = await client.GetAsync("bucketa/bucketb/bucketc"); 
var myJson = response.Body; 

Po tym, można łatwo iterację właściwości zwróconego json obiektu (np Iterating over JSON object in C#).

Oczywiście, gdybyś miał bezpośrednią kontrolę nad strukturą danych, zaleca się dalsze spłasz- czenie (patrz: https://firebase.google.com/docs/database/android/structure-data).

Nie jestem całkowicie pewien, co masz na myśli przez "Ale to właśnie zwróciło ciąg typu obiektu." .OnceAsync<RealClass>(); zwróci kolekcję obiektów typu FirebaseObject (oryginalny obiekt jest odsłonięty jako właściwość Object) - nigdy String.

Odpowiedz zaktualizować

Brzmi jakby zapytanie idzie jedna warstwa głębsza niż Przypuszczałem z opisem wy danych. Czy to działa?

await firebase.Child("bucketa/bucketb/bucketc").OnceAsync<Dictiona‌​ry<string, RealCl‌​ass>>(); 
+0

Dzięki za odpowiedź. Tak więc jestem czysty, widzę, że mówisz, że nie mogę zastosować podejścia wieloznacznego, ale czy nadal można to zrobić, definiując klasę z 2 klasami otaczającymi, tak jak tu piszesz: " "dzieci" tego drzewa (someguidtypekey/anotherguidtypekey) pojawią się jako właściwości obiektu z GUIDkey jako nazwą właściwości ". Otrzymałbym więc tablicę obiektów 'WrapperClass', gdzie mógłbym spłaszczyć tę tablicę do poziomu' RealClass'. Jest to TYLKO potrzebne dane, więc nie mam problemu z opracowaniem czegoś specjalnie dla tej struktury danych. – ganders

+0

Problem polega na tym, że elementy podrzędne nie będą wyświetlane jako tablica lub obiekt słownikowy (z parami klucz-wartość), ale jako nazwy właściwości o sztywnych kodach, które należy znać podczas kompilacji. Oznacza to, że możesz to zrobić tylko wtedy, gdy znasz wartości "someguidtypekey" i "anotherguidtypekey" podczas kompilacji. Jednakże, jeśli masz tę listę, znacznie łatwiej będzie iterować ją i osobno zapytać każdą ścieżkę (używając 'var stats = wait firebase.Child (" bucketa/bucketb/bucketc/key1/key2 "). OnceAsync ();'). –

+0

Gdy otrzymam już te dane, czy nie mogę po prostu powtórzyć wszystkich kluczy w elemencie słownika i spłaszczyć w ten sposób? W ten sposób: 'foreach (element var w myDictionary.Keys) { foreach (var innerItem w item.Keys) {flattenToThisObject (innerItem); } } '(Nie ma mnie w domu, więc nie mogę tego jeszcze przetestować/PoC ...) – ganders