-
Notifications
You must be signed in to change notification settings - Fork 4.7k
Commit
# Why To be able to register at Expo server we need to identify the device with a UUID. # How Implemented a non-exported module which: - uses the same storage as kernel does for the UUID (in native, on web uses `localStorage`) - if the ID is missing, it generates and saves a new one. # Test Plan None yet, implementing `getExpoPushTokenAsync` will be a test for this module.
- Loading branch information
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Large diffs are not rendered by default.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
package expo.modules.notifications.installationid; | ||
|
||
import android.content.Context; | ||
import android.content.SharedPreferences; | ||
|
||
import java.util.UUID; | ||
|
||
public class InstallationId { | ||
private static final String PREFERENCES_KEY = "host.exp.exponent.SharedPreferences"; | ||
private static final String UUID_KEY = "uuid"; | ||
private SharedPreferences mSharedPreferences; | ||
|
||
public InstallationId(Context context) { | ||
mSharedPreferences = context.getSharedPreferences(PREFERENCES_KEY, Context.MODE_PRIVATE); | ||
} | ||
|
||
public String getId() { | ||
return getOrCreateId(); | ||
} | ||
|
||
private String getOrCreateId() { | ||
String uuid = mSharedPreferences.getString(UUID_KEY, null); | ||
if (uuid != null) { | ||
return uuid; | ||
} | ||
|
||
uuid = UUID.randomUUID().toString(); | ||
mSharedPreferences.edit().putString(UUID_KEY, uuid).apply(); | ||
return uuid; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
package expo.modules.notifications.installationid; | ||
|
||
import android.content.Context; | ||
|
||
import org.unimodules.core.ExportedModule; | ||
import org.unimodules.core.Promise; | ||
import org.unimodules.core.interfaces.ExpoMethod; | ||
|
||
public class InstallationIdProvider extends ExportedModule { | ||
private static final String EXPORTED_NAME = "NotificationsInstallationIdProvider"; | ||
|
||
private InstallationId mInstallationId; | ||
|
||
public InstallationIdProvider(Context context) { | ||
super(context); | ||
mInstallationId = new InstallationId(context); | ||
} | ||
|
||
@Override | ||
public String getName() { | ||
return EXPORTED_NAME; | ||
} | ||
|
||
@ExpoMethod | ||
public void getInstallationIdAsync(Promise promise) { | ||
promise.resolve(mInstallationId.getId()); | ||
} | ||
} |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
// Copyright 2018-present 650 Industries. All rights reserved. | ||
|
||
#import <UMCore/UMExportedModule.h> | ||
|
||
NS_ASSUME_NONNULL_BEGIN | ||
|
||
@interface EXInstallationIdProvider : UMExportedModule | ||
|
||
@end | ||
|
||
NS_ASSUME_NONNULL_END |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
// Copyright 2018-present 650 Industries. All rights reserved. | ||
|
||
#import <EXNotifications/EXInstallationIdProvider.h> | ||
|
||
NSString * const kEXDeviceInstallUUIDKey = @"EXDeviceInstallUUIDKey"; | ||
|
||
@implementation EXInstallationIdProvider | ||
|
||
UM_EXPORT_MODULE(NotificationsInstallationIdProvider) | ||
|
||
UM_EXPORT_METHOD_AS(getInstallationIdAsync, getInstallationIdAsyncWithResolver:(UMPromiseResolveBlock)resolve rejecter:(UMPromiseRejectBlock)reject) | ||
{ | ||
resolve([self getInstallationId]); | ||
} | ||
|
||
- (NSString *)getInstallationId | ||
{ | ||
NSString *uuid = [[NSUserDefaults standardUserDefaults] stringForKey:kEXDeviceInstallUUIDKey]; | ||
if (!uuid) { | ||
uuid = [[NSUUID UUID] UUIDString]; | ||
[[NSUserDefaults standardUserDefaults] setObject:uuid forKey:kEXDeviceInstallUUIDKey]; | ||
} | ||
return uuid; | ||
} | ||
|
||
@end |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
import { NativeModulesProxy } from '@unimodules/core'; | ||
|
||
import { InstallationIdProvider } from './InstallationIdProvider.types'; | ||
|
||
export default (NativeModulesProxy.NotificationsInstallationIdProvider as any) as InstallationIdProvider; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
import { ProxyNativeModule } from '@unimodules/core'; | ||
|
||
export interface InstallationIdProvider extends ProxyNativeModule { | ||
getInstallationIdAsync: () => Promise<string>; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
import UUID from 'uuid-js'; | ||
|
||
import { InstallationIdProvider } from './InstallationIdProvider.types'; | ||
|
||
const INSTALLATION_ID_KEY = 'EXPO_NOTIFICATIONS_INSTALLATION_ID'; | ||
|
||
// Lazy fallback installationId per session initializer | ||
let getFallbackInstallationId = () => { | ||
const sessionInstallationId = UUID.create().toString(); | ||
getFallbackInstallationId = () => sessionInstallationId; | ||
}; | ||
|
||
export default { | ||
getInstallationIdAsync: async () => { | ||
let installationId; | ||
|
||
try { | ||
installationId = localStorage.getItem(INSTALLATION_ID_KEY); | ||
if (!installationId || typeof installationId !== 'string') { | ||
installationId = UUID.create().toString(); | ||
localStorage.setItem(INSTALLATION_ID_KEY, installationId); | ||
} | ||
} catch (error) { | ||
installationId = getFallbackInstallationId(); | ||
} | ||
|
||
return installationId; | ||
}, | ||
// mock implementations | ||
addListener: () => {}, | ||
removeListeners: () => {}, | ||
} as InstallationIdProvider; |