Skip to content

Instantly share code, notes, and snippets.

@axeldelafosse
Last active October 12, 2023 19:57
Show Gist options
  • Save axeldelafosse/8cd7274501180257ae4951a0dc8759c2 to your computer and use it in GitHub Desktop.
Save axeldelafosse/8cd7274501180257ae4951a0dc8759c2 to your computer and use it in GitHub Desktop.
[DEPRECATED] React Native MMKV - Config plugin for Expo. You need to use "react-native-mmkv": "^1.6.2"
// DEPRECATED
const {
withDangerousMod,
WarningAggregator,
AndroidConfig,
withAppBuildGradle,
} = require("@expo/config-plugins");
const path = require("path");
const fs = require("fs");
function getMMKVJSIModulePackage(packageName) {
return `package ${packageName};
import com.facebook.react.bridge.JSIModuleSpec;
import com.facebook.react.bridge.JavaScriptContextHolder;
import com.facebook.react.bridge.ReactApplicationContext;
import com.swmansion.reanimated.ReanimatedJSIModulePackage;
import com.reactnativemmkv.MmkvModule;
import java.util.Collections;
import java.util.List;
public class MMKVJSIModulePackage extends ReanimatedJSIModulePackage {
@Override
public List<JSIModuleSpec> getJSIModules(ReactApplicationContext reactApplicationContext, JavaScriptContextHolder jsContext) {
MmkvModule.install(jsContext, reactApplicationContext.getFilesDir().getAbsolutePath() + "/mmkv");
return super.getJSIModules(reactApplicationContext, jsContext);
}
}`;
}
async function readFileAsync(path) {
return fs.promises.readFile(path, "utf8");
}
async function saveFileAsync(path, content) {
return fs.promises.writeFile(path, content, "utf8");
}
function getPackageRoot(projectRoot) {
return path.join(projectRoot, "android", "app", "src", "main", "java");
}
function getCurrentPackageName(projectRoot, packageRoot) {
const mainApplication = AndroidConfig.Paths.getProjectFilePath(
projectRoot,
"MainApplication"
);
const packagePath = path.dirname(mainApplication);
const packagePathParts = path
.relative(packageRoot, packagePath)
.split(path.sep)
.filter(Boolean);
return packagePathParts.join(".");
}
async function editMainApplication(config, action) {
const mainApplicationPath = AndroidConfig.Paths.getProjectFilePath(
config.modRequest.projectRoot,
"MainApplication"
);
try {
const mainApplication = action(await readFileAsync(mainApplicationPath));
return await saveFileAsync(mainApplicationPath, mainApplication);
} catch (e) {
WarningAggregator.addWarningAndroid(
"react-native-mmkv",
`Couldn't modify MainApplication.java - ${e}.`
);
}
}
async function createMMKVJSIModulePackage(config, action) {
const projectRoot = config.modRequest.projectRoot;
const packageRoot = getPackageRoot(projectRoot);
const packageName = getCurrentPackageName(projectRoot, packageRoot);
const filePath = path.join(
packageRoot,
`${packageName.split(".").join("/")}/MMKVJSIModulePackage.java`
);
try {
return await saveFileAsync(filePath, getMMKVJSIModulePackage(packageName));
} catch (e) {
WarningAggregator.addWarningAndroid(
"react-native-mmkv",
`Couldn't create MMKVJSIModulePackage.java - ${e}.`
);
}
}
const withMMKVJSIModulePackage = (config) => {
return withDangerousMod(config, [
"android",
async (config) => {
await createMMKVJSIModulePackage(config);
return config;
},
]);
};
const withMainApplication = (config) => {
return withDangerousMod(config, [
"android",
async (config) => {
await editMainApplication(config, (mainApplication) => {
if (mainApplication.includes('return new MMKVJSIModulePackage();')) {
return mainApplication;
}
mainApplication = mainApplication.replace(
` @Override
protected String getJSMainModuleName() {
return "index";
}`,
` @Override
protected String getJSMainModuleName() {
return "index";
}
@Override
protected JSIModulePackage getJSIModulePackage() {
return new MMKVJSIModulePackage();
}`
);
return mainApplication;
});
return config;
},
]);
};
const withCustomAppBuildGradle = (config) => {
return withAppBuildGradle(config, (config) => {
if (
config.modResults.contents.includes(
`implementation project(':react-native-mmkv')`
)
) {
return config;
}
config.modResults.contents = config.modResults.contents.replace(
`implementation "com.facebook.react:react-native:+" // From node_modules`,
`implementation "com.facebook.react:react-native:+" // From node_modules
implementation project(':react-native-mmkv')`
);
return config;
});
};
module.exports = function withMMKV(config) {
config = withMMKVJSIModulePackage(config);
config = withMainApplication(config);
config = withCustomAppBuildGradle(config);
return config;
};
@igorcesarcode
Copy link

@mariomurrent-softwaresolutions

@igorcesarcode Same here, does not work for me

@axeldelafosse
Copy link
Author

@junaiddarajat you can edit the config plugin to your needs-- it should be pretty straightforward!

@hirbod nope, the latest version is now working correctly. you can try v1.6.2 🎉

@igorcesarcode @mariomurrent-softwaresolutions can you try with the latest code from the gist (it is updated) and v1.6.2 please?

@hirbod
Copy link

hirbod commented Jan 5, 2022

@axeldelafosse yeah, already figured that yesterday. @Kudo might take over soon when he has time (no eta) and provide a solution without a dangerous approach.

SDK 44 is still failing though, because of a folly lib, but Marc will release a fix today which will fix this. Thanks for your effort!

Edit: 1.6.2 is already released an I can confirm that it is working perfectly for me on SDK 44 now. Thanks @axeldelafosse

You might want to update the title at the top

@axeldelafosse
Copy link
Author

@Kudo might take over soon when he has time (no eta) and provide a solution without a dangerous approach.

Yeah this is why I didn't wanted to release this config plugin... A lot of people were asking for it but I don't want to maintain this.

1.6.2 is already released an I can confirm that it is working perfectly for me on SDK 44 now

Yeah I was waiting for this release to get back to you!

You might want to update the title at the top

Good call. Done. Have a nice day :)

@mariomurrent-softwaresolutions

@axeldelafosse: Yes, with the updated version it works. Thx

@axeldelafosse
Copy link
Author

🎉

@mariomurrent-softwaresolutions
Copy link

mariomurrent-softwaresolutions commented May 3, 2022

Im currently getting the following errors:

[RUN_GRADLEW] .../MainApplication.java:47: error: cannot find symbol
[RUN_GRADLEW]     protected JSIModulePackage getJSIModulePackage() {
[RUN_GRADLEW]               ^
[RUN_GRADLEW]   symbol: class JSIModulePackage
[RUN_GRADLEW] .../MMKVJSIModulePackage.java:16: error: method install in class MmkvModule cannot be applied to given types;
[RUN_GRADLEW]             MmkvModule.install(jsContext, reactApplicationContext.getFilesDir().getAbsolutePath() + "/mmkv");
[RUN_GRADLEW]                       ^
[RUN_GRADLEW]   required: String
[RUN_GRADLEW]   found:    JavaScriptContextHolder,String
[RUN_GRADLEW]   reason: actual and formal argument lists differ in length
[RUN_GRADLEW] Note: .../MMKVJSIModulePackage.java uses or overrides a deprecated API.
[RUN_GRADLEW] Note: Recompile with -Xlint:deprecation for details.

Any ideas? I tried it with the expo beta SDK 45

@hirbod
Copy link

hirbod commented May 3, 2022

This plugin is NOT compatible anymore with SDK 45 - and you don't need a plugin with the newest MMKV plugin, but it will crash on Expo when you reload via dev menu (no problem in release mode though). I created two tickets for this but it's not resolved yet

@mariomurrent-softwaresolutions

Oh, but the EAS build is working with the latest release?

@hirbod
Copy link

hirbod commented May 3, 2022

As said, react-native-mmkv does not need any config-plugins anymore (you need the current version). It is working out of the box, the only downside is that on iOS using reload (not fast refresh) from the dev menu will crash the app. It's not a big deal as long as you're not reloading and won't be an issue with production builds. Building with EAS is possible.

@mariomurrent-softwaresolutions

Nice, I'll try it out asap. Thx for the information

@Laviniaxyz
Copy link

Hello,

Can someone share their latest, functional react-native-mmkv-plugin file?
I have tried using the shared plugin, but I get the same error: "Failed to create new MMKV instance...etc".

I use expo sdk 44.0.0 & react-native-mmkv 1.6.2.
I have also added the plugin in my app.json file:
"plugins": [
"./react-native-mmkv-plugin.js"
]

@mariomurrent-softwaresolutions

Hello,

Can someone share their latest, functional react-native-mmkv-plugin file? I have tried using the shared plugin, but I get the same error: "Failed to create new MMKV instance...etc".

I use expo sdk 44.0.0 & react-native-mmkv 1.6.2. I have also added the plugin in my app.json file: "plugins": [ "./react-native-mmkv-plugin.js" ]

Are you using the EAS build? Did you rebuild the dev client?

@hirbod
Copy link

hirbod commented Jul 8, 2022

You don’t need this plugin anymore. Just upgrade to SDK 45.0.6 (make sure not to stay on 45.0.0) and it just works without a conf plugin.

@mgscreativa
Copy link

mgscreativa commented Jul 15, 2022

Hi @hirbod ! which version of react-native-mmkv should I use with SDK 45.0.6? Ran npm install and got "react-native-mmkv": "^2.4.3", is that ok?

@hirbod
Copy link

hirbod commented Jul 15, 2022

The current version works. (Only with custom dev client)

@mgscreativa
Copy link

Thanks @hirbod ! Yes, actually I'm using custom dev client, so will test it out. Thanks!

@Laviniaxyz
Copy link

Hello,
Can someone share their latest, functional react-native-mmkv-plugin file? I have tried using the shared plugin, but I get the same error: "Failed to create new MMKV instance...etc".
I use expo sdk 44.0.0 & react-native-mmkv 1.6.2. I have also added the plugin in my app.json file: "plugins": [ "./react-native-mmkv-plugin.js" ]

Are you using the EAS build? Did you rebuild the dev client?

No, I was hoping to use this library in an expo managed environment, but from what I see it is not supported.

@hirbod
Copy link

hirbod commented Aug 29, 2022

@Laviniaxyz this library adds native code, so using the managed env is indeed not possible. But creating a custom dev client with Xcode/Studio or EAS is actually straightforward and like 10 minutes of effort.

@samrith-s
Copy link

Does this work with Expo SDK 47?

@hirbod
Copy link

hirbod commented Nov 19, 2022

There is no need for this plug-in anymore. It works ootb with a dev client

@samrith-s
Copy link

Ok, do I still need to run expo prebuild?

@hirbod
Copy link

hirbod commented Nov 21, 2022

Yes

@mariomurrent-softwaresolutions

Is this still valid? Seems to be broken in SDK 48

@hirbod
Copy link

hirbod commented Feb 13, 2023

Still valid. You need to make sure to update mmkv for RN 0.71

@mariomurrent-softwaresolutions
Copy link

mariomurrent-softwaresolutions commented Feb 13, 2023

@hirbod I upgraded mmkv to 2.7.1 but this did not help either

@simon-ojok
Copy link

@axeldelafosse How about if you create npm page that we can install intead of us copying these codes

@nandorojo
Copy link

@simon-ojok he provided this for free, you’re welcome to do that yourself if you want.

but also this is deprecated and isn’t needed anymore

@biratdevpoudel
Copy link

There is no need for this plug-in anymore. It works ootb with a dev client

yes worked for me aswell

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment