Skip to content

Commit 77ab896

Browse files
committed
code/push: filter out based on recent appInstallId
Using latest token doesn't work for a lot of reasons. Instead, we need to use the most recent _per device_.
1 parent dabb7d0 commit 77ab896

File tree

1 file changed

+63
-27
lines changed

1 file changed

+63
-27
lines changed

pkg/code/push/data.go

Lines changed: 63 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,14 @@ package push
33
import (
44
"context"
55
"slices"
6+
"strings"
67

78
"github.com/sirupsen/logrus"
89

910
"github.com/code-payments/code-server/pkg/code/common"
1011
code_data "github.com/code-payments/code-server/pkg/code/data"
1112
push_data "github.com/code-payments/code-server/pkg/code/data/push"
13+
"github.com/code-payments/code-server/pkg/pointer"
1214
push_lib "github.com/code-payments/code-server/pkg/push"
1315
)
1416

@@ -105,38 +107,72 @@ func sendMutableNotificationToOwner(
105107
}
106108

107109
log.WithField("tokens", pushTokenRecords).Info("Found push tokens")
110+
111+
// We reverse sort the tokens based on creation date to prioritze
112+
// recenty tokens. Furthermore, this means that in the case of a
113+
// detected dedupe, we use the most recent token.
108114
slices.SortFunc(pushTokenRecords, func(a, b *push_data.Record) int {
109-
return a.CreatedAt.Compare(b.CreatedAt)
115+
return b.CreatedAt.Compare(a.CreatedAt)
110116
})
111117

112-
pushTokenRecord := pushTokenRecords[len(pushTokenRecords)-1]
113-
log = log.WithField("push_token", pushTokenRecord.PushToken)
118+
pushedTokens := make(map[string]struct{})
119+
pushedDevices := make(map[string]struct{})
114120

115-
// Try push
116-
switch pushTokenRecord.TokenType {
117-
case push_data.TokenTypeFcmApns:
118-
log.Info("Sending mutable push")
119-
err = pusher.SendMutableAPNSPush(
120-
ctx,
121-
pushTokenRecord.PushToken,
122-
titleKey,
123-
string(notificationType),
124-
titleKey, // All mutable pushes have a thread ID that's the title
125-
kvs,
126-
)
127-
case push_data.TokenTypeFcmAndroid:
128-
// todo: anything special required for Android?
129-
log.Info("Sending data push")
130-
err = pusher.SendDataPush(
131-
ctx,
132-
pushTokenRecord.PushToken,
133-
kvs,
134-
)
135-
}
121+
for _, pushTokenRecord := range pushTokenRecords {
122+
if _, ok := pushedTokens[pushTokenRecord.PushToken]; ok {
123+
continue
124+
}
136125

137-
if err != nil {
138-
log.WithError(err).Warn("failure sending push notification")
139-
onPushError(ctx, data, pusher, pushTokenRecord)
126+
// In the case of apple, we attempt to dedupe based on app install id
127+
var appInstallId string
128+
if pushTokenRecord.TokenType == push_data.TokenTypeFcmApns {
129+
appInstallId = *pointer.StringOrDefault(pushTokenRecord.AppInstallId, "")
130+
if appInstallId == "" {
131+
// Legacy token: Attempt to take it from the token itself
132+
parts := strings.Split(pushTokenRecord.PushToken, ":")
133+
if len(parts) == 2 {
134+
appInstallId = parts[0]
135+
}
136+
}
137+
138+
if appInstallId != "" {
139+
if _, ok := pushedDevices[appInstallId]; ok {
140+
continue
141+
}
142+
}
143+
}
144+
145+
// Try push
146+
switch pushTokenRecord.TokenType {
147+
case push_data.TokenTypeFcmApns:
148+
log.Info("Sending mutable push")
149+
err = pusher.SendMutableAPNSPush(
150+
ctx,
151+
pushTokenRecord.PushToken,
152+
titleKey,
153+
string(notificationType),
154+
titleKey, // All mutable pushes have a thread ID that's the title
155+
kvs,
156+
)
157+
case push_data.TokenTypeFcmAndroid:
158+
// todo: anything special required for Android?
159+
log.Info("Sending data push")
160+
err = pusher.SendDataPush(
161+
ctx,
162+
pushTokenRecord.PushToken,
163+
kvs,
164+
)
165+
}
166+
167+
if err != nil {
168+
log.WithError(err).Warn("failure sending push notification")
169+
onPushError(ctx, data, pusher, pushTokenRecord)
170+
} else {
171+
pushedTokens[pushTokenRecord.PushToken] = struct{}{}
172+
if appInstallId != "" {
173+
pushedDevices[appInstallId] = struct{}{}
174+
}
175+
}
140176
}
141177

142178
return nil

0 commit comments

Comments
 (0)