blockchain-certificates / wallet-android

An Android app for Blockcerts
MIT License
38 stars 47 forks source link

Certificates with metadata defined as multiple types #31

Open ghost opened 5 years ago

ghost commented 5 years ago

Certificates with metadata such as below will cause the information panel of the certificate to not load any of the metadata besides the basic information.

{\"title\":\"Test\",\"isVar\":true,\"originalValue\":\"metadata.recipient.test\",\"type\":[\"string\",\"null\"]}

This is an example certificate that should have this error on android: https://certificates.learningmachine.com/certificate/a4dcb4548abf5a5ba7f67ba3512fc04b

The issue is having type be an array instead of a string. More information about this: https://cswr.github.io/JsonSchema/spec/multiple_types/

It should be valid, yet the google json library does not seem to allow this. This issue is not present on iOS.

raiseandfall commented 5 years ago

Screenshot

screenshot_20190213-143754

Stack log

[d] LMFragment: onPause: CertificateFragment
[d] LMFragment: onCreate: CertificateInfoFragment
[e] CertificateInfoFragment: Malformed metadata JSON
com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected STRING but was BEGIN_ARRAY at path $.type
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:224)
at com.google.gson.Gson.fromJson(Gson.java:887)
at com.google.gson.Gson.fromJson(Gson.java:952)
at com.google.gson.internal.bind.TreeTypeAdapter$GsonContextImpl.deserialize(TreeTypeAdapter.java:162)
at com.learningmachine.android.app.data.cert.metadata.MetadataTypeAdapter.getGroupDefinitions(MetadataTypeAdapter.java:62)
at com.learningmachine.android.app.data.cert.metadata.MetadataTypeAdapter.deserialize(MetadataTypeAdapter.java:35)
at com.learningmachine.android.app.data.cert.metadata.MetadataTypeAdapter.deserialize(MetadataTypeAdapter.java:17)
at com.google.gson.internal.bind.TreeTypeAdapter.read(TreeTypeAdapter.java:69)
at com.google.gson.Gson.fromJson(Gson.java:887)
at com.google.gson.Gson.fromJson(Gson.java:852)
at com.google.gson.Gson.fromJson(Gson.java:801)
at com.google.gson.Gson.fromJson(Gson.java:773)
at com.learningmachine.android.app.data.cert.metadata.MetadataParser.fromJson(MetadataParser.java:27)
at com.learningmachine.android.app.ui.cert.CertificateInfoFragment$CertificateInfoAdapter.getMetadata(CertificateInfoFragment.java:187)
at com.learningmachine.android.app.ui.cert.CertificateInfoFragment$CertificateInfoAdapter.<init>(CertificateInfoFragment.java:134)
at com.learningmachine.android.app.ui.cert.CertificateInfoFragment.lambda$onCreateView$4$CertificateInfoFragment(CertificateInfoFragment.java:115)
at com.learningmachine.android.app.ui.cert.CertificateInfoFragment$$Lambda$2.call(Unknown Source:4)
at rx.internal.util.ActionSubscriber.onNext(ActionSubscriber.java:39)
at rx.observers.SafeSubscriber.onNext(SafeSubscriber.java:134)
at rx.internal.util.ScalarSynchronousObservable$WeakSingleProducer.request(ScalarSynchronousObservable.java:276)
at rx.Subscriber.setProducer(Subscriber.java:209)
at rx.Subscriber.setProducer(Subscriber.java:205)
at rx.internal.util.ScalarSynchronousObservable$3.call(ScalarSynchronousObservable.java:233)
at rx.internal.util.ScalarSynchronousObservable$3.call(ScalarSynchronousObservable.java:228)
at rx.Observable.subscribe(Observable.java:10352)
at rx.Observable.subscribe(Observable.java:10319)
at rx.Observable.subscribe(Observable.java:10159)
at com.learningmachine.android.app.ui.cert.CertificateInfoFragment.onCreateView(CertificateInfoFragment.java:114)
at android.support.v4.app.Fragment.performCreateView(Fragment.java:2346)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1428)
at android.support.v4.app.FragmentManagerImpl.moveFragmentToExpectedState(FragmentManager.java:1759)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1827)
at android.support.v4.app.BackStackRecord.executeOps(BackStackRecord.java:797)
at android.support.v4.app.FragmentManagerImpl.executeOps(FragmentManager.java:2596)
at android.support.v4.app.FragmentManagerImpl.executeOpsTogether(FragmentManager.java:2383)
at android.support.v4.app.FragmentManagerImpl.removeRedundantOperationsAndExecute(FragmentManager.java:2338)
at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:2245)
at android.support.v4.app.FragmentManagerImpl.dispatchStateChange(FragmentManager.java:3248)
at android.support.v4.app.FragmentManagerImpl.dispatchActivityCreated(FragmentManager.java:3200)
at android.support.v4.app.FragmentController.dispatchActivityCreated(FragmentController.java:195)
at android.support.v4.app.FragmentActivity.onStart(FragmentActivity.java:597)
at android.support.v7.app.AppCompatActivity.onStart(AppCompatActivity.java:177)
at com.learningmachine.android.app.ui.LMActivity.onStart(LMActivity.java:85)
at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1391)
at android.app.Activity.performStart(Activity.java:7165)
at android.app.ActivityThread.handleStartActivity(ActivityThread.java:2975)
at android.app.servertransaction.TransactionExecutor.performLifecycleSequence(TransactionExecutor.java:180)
at android.app.servertransaction.TransactionExecutor.cycleToPath(TransactionExecutor.java:165)
at android.app.servertransaction.TransactionExecutor.executeLifecycleState(TransactionExecutor.java:142)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:70)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1816)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:193)
at android.app.ActivityThread.main(ActivityThread.java:6718)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
Caused by: java.lang.IllegalStateException: Expected STRING but was BEGIN_ARRAY at path $.type
at com.google.gson.internal.bind.JsonTreeReader.nextString(JsonTreeReader.java:180)
at com.google.gson.internal.bind.TypeAdapters$EnumTypeAdapter.read(TypeAdapters.java:799)
at com.google.gson.internal.bind.TypeAdapters$EnumTypeAdapter.read(TypeAdapters.java:772)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.read(ReflectiveTypeAdapterFactory.java:129)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:220)
... 56 more