将Go Struct解码为expo推送通知响应?

huangapple go评论72阅读模式
英文:

Go Struct to decode expo push notification response?

问题

我正在使用Go语言编写一个服务,该服务向Expo后端发送推送通知。一旦发出HTTP调用,Expo会以以下格式响应(根据Expo的规定):

{
  "data": [
    {
      "status": "error" | "ok",
      "id": string, // 这是收据ID
      // 如果status === "error"
      "message": string,
      "details": JSON
    },
    ...
  ],
  // 仅在整个请求出现错误时才填充
  "errors": [{
    "code": number,
    "message": string
  }]
}

这是一个提供的响应示例:

{
  "data": [
    {
      "status": "error",
      "message": "\"ExponentPushToken[xxxxxxxxxxxxxxxxxxxxxx]\" is not a registered push notification recipient",
      "details": {
        "error": "DeviceNotRegistered"
      }
    },
    {
      "status": "ok",
      "id": "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"
    }
  ]
}

我创建了一个用于解码响应的结构体。现在我在尝试解码"details"字段的响应时遇到了错误,无论我在结构体中使用什么类型。我该如何处理Expo标记为"JSON"的字段?

import (
	uuid "github.com/satori/go.uuid"
)

type PushResult struct {
	Errors []ErrorDetails `json:"errors,omitempty"`
	Datas  []DataPart     `json:"data,omitempty"`
}

type ErrorDetails struct {
	Code    int32  `json:"code,omitempty"`
	Message string `json:"message,omitempty"`
}

type DataPart struct {
	Status  string    `json:"status,omitempty"`
	ID      uuid.UUID `json:"id,omitempty"`
	Message string    `json:"message,omitempty"`
	Details string    `json:"details,omitempty"` // 也尝试过map[string]string和interface{}
}

这是我正在使用的结构体。我还尝试了根据示例进行如下更改:

type DataPart struct {
	Status  string `json:"status,omitempty"`
	ID      uuid.UUID `json:"id,omitempty"`
	Message string `json:"message,omitempty"`
	Details struct{
           Error string `json:"error"`} `json:"details,omitempty"` 
}

但每次都会出现类似"json: cannot unmarshal object into Go struct field DataPart.data.details"的错误提示。

英文:

I am making a service in go that sends push notification to Expo Backend. Once the http call is made Expo respond with bellow format(according to Expo):

{
  "data": [
    {
      "status": "error" | "ok",
      "id": string, // this is the Receipt ID
      // if status === "error"
      "message": string,
      "details": JSON
    },
    ...
  ],
  // only populated if there was an error with the entire request
  "errors": [{
    "code": number,
    "message": string
  }]
}

And here is an provioded example of a response:

{
  "data": [
    {
      "status": "error",
      "message": "\\\"ExponentPushToken[xxxxxxxxxxxxxxxxxxxxxx]\\\" is not a registered push notification recipient",
      "details": {
        "error": "DeviceNotRegistered"
      }
    },
    {
      "status": "ok",
      "id": "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"
    }
  ]
}

I created struct to decode the response.Now i get a error try to decode the reponse for the "details" field, No matter what type i use in my Struct. How can i deal with that field that expo mark as "JSON"?

import (
	uuid "github.com/satori/go.uuid"
)


type PushResult struct {
	Errors []ErrorDetails `json:"errors,omitempty"`
	Datas   []DataPart     `json:"data,omitempty"`
}
type ErrorDetails struct {
	Code    int32  `json:"code,omitempty"`
	Message string `json:"message,omitempty"`
}
type DataPart struct {
	Status  string    `json:"status,omitempty"`
	ID      uuid.UUID `json:"id,omitempty"`
	Message string    `json:"message,omitempty"`
	Details string `json:"details,omitempty"` //also tried map[string]string and interface{}

}

This is the struct i am using. i also tried this by looking at the example:

type DataPart struct {
	Status  string    `json:"status,omitempty"`
	ID      uuid.UUID `json:"id,omitempty"`
	Message string    `json:"message,omitempty"`
	Details struct{
           Error string `json:"error"`} `json:"details,omitempty"` 

}

But every time get an error like "json: cannot unmarshal object into Go struct field DataPart.data.details"

答案1

得分: 2

我刚刚使用你的响应示例创建了一个结构体,并且完全正常工作。

Playground

话虽如此,如果你想要更好地调试"解组错误",你可以将其解包。这样你就可以打印额外的数据。

var t *json.UnmarshalTypeError
if errors.As(err, &t) {
    spew.Dump(t)
}

示例 -> 我将错误类型更改为整数,以便我可以伪造错误。

注意,你的"Datas"是一个数组,只有第一个有错误。

英文:

I just created you struct using your response exemple and it worked completly fine.

Playground

That said if you wana a better way of debugging an "unmarshal error" you can unwrap it. That way you can print aditional data.

var t *json.UnmarshalTypeError
if errors.As(err, &t) {
	spew.Dump(t)
}

Example -> I changed the error type to integer so I can fake the error.

OBS: Note that your "Datas" is an array and only the 1st one have an error.

huangapple
  • 本文由 发表于 2022年3月24日 23:26:49
  • 转载请务必保留本文链接:https://go.coder-hub.com/71605188.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定