I got "x.509 certificate signed by unknown authority" error message when I tried to send notifications to the Expo Push Notification server.
My server written in Golang stores expo push tokens. Then, it loads those tokens and build expo.PushMessage
list and push them using PublishMultiple
function.
I have two servers, one is for test and the other is for the production. It works well in the test server. I got push notification on my testing phone. So, I updated my production server, then the production server produces x.509 certificate signed by unknown authority
message.
First, I suspect that my expo push token had been corrupted, but the push token works well when I used Expo push notifications tool.
I am not sure where to look for a solution. Can anyone help me? I'll revise the question if you want to know about my server code or settings. At this moment, I'm not sure which part of code or settings should be provided to find a solution.
The following codes are around the only place that the error can occur.
import (
expo "github.com/oliveroneill/exponent-server-sdk-golang/sdk"
"github.com/pkg/errors"
)
type Client struct {
PushClient *expo.PushClient
}
func NewClient() *Client {
client := expo.NewPushClient(nil)
return &Client{PushClient: client}
}
func (c *Client) PushNotifications(deviceKeys []string, title string, body string) (error, map[string]string) {
messages := make([]expo.PushMessage, 0)
for _, deviceKey := range deviceKeys {
pushToken, err := expo.NewExponentPushToken(deviceKey)
if err != nil {
continue
}
messages = append(messages, expo.PushMessage{
To: pushToken,
Body: body,
Data: nil,
Sound: "default",
Title: title,
Priority: expo.DefaultPriority,
ChannelID: "default",
})
}
// This is only place the error can occur
// PublishMultiple function is a part of the Expo SDK
responses, err := c.PushClient.PublishMultiple(messages)
if err != nil {
return errors.WithStack(err), nil
}
sentErrors := make(map[string]string)
for index, response := range responses {
err := response.ValidateResponse()
if err != nil && index >= len(deviceKeys) {
sentErrors[deviceKeys[index]] = err.Error()
}
}
return nil, sentErrors
}
A dockerfile to build my production server:
FROM golang:1.13-alpine as builder
WORKDIR /usr/src/app
ARG app
COPY . .
RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -mod vendor -a -ldflags '-s' -o main ./apps/$app
FROM scratch
COPY --from=builder /usr/src/app/main /app/main
WORKDIR /app
CMD ["./main"]
golang:*-alpine
images are intentionally minimal and do not have a system certificate pool.
The simplest solution is to add it yourself when building your docker image by adding:
RUN apk add --no-cache ca-certificates