Code Monkey home page Code Monkey logo

ammarahm-ed / react-native-mmkv-storage Goto Github PK

View Code? Open in Web Editor NEW
1.5K 15.0 103.0 4.26 MB

An ultra fast (0.0002s read/write), small & encrypted mobile key-value storage framework for React Native written in C++ using JSI

Home Page: https://rnmmkv.now.sh

License: MIT License

Java 5.33% JavaScript 1.86% Objective-C 2.13% Ruby 0.38% CMake 0.87% C++ 62.61% Objective-C++ 4.76% Assembly 5.79% C 4.79% TypeScript 11.47%
react-native asyncstorage mmkv-database java objective-c storage android ios fast-storage react

react-native-mmkv-storage's Introduction

License: MIT Android iOS

Install the library

npm install react-native-mmkv-storage

For expo bare workflow

expo prebuild

Get Started with Documentation

What it is

This library aims to provide a fast & reliable solution for you data storage needs in react-native apps. It uses MMKV by Tencent under the hood on Android and iOS both that is used by their WeChat app(more than 1 Billion users). Unlike other storage solutions for React Native, this library lets you store any kind of data type, in any number of database instances, with or without encryption in a very fast and efficient way. Read about it on this blog post I wrote on dev.to

Learn how to build your own module with JSI on my blog

0.9.0 Breaking change

Works only with react native 0.71.0 and above. If you are on older version of react native, keep using 0.8.x.

Features

Written in C++ using JSI

Starting from v0.5.0 the library has been rewritten in C++ on Android and iOS both. It employs React Native JSI making it the fastest storage option for React Native.

Simple and lightweight

(~ 50K Android/30K iOS) and even smaller when packaged.

Fast and Efficient (0.0002s Read/Write Speed)

MMKV uses mmap to keep memory synced with file, and protobuf to encode/decode values to achieve best performance. You can see the benchmarks here: Android & iOS

Reactive using useMMKVStorage & useIndex Hooks

Hooks let's the storage update your app when a change takes place in storage.

useMMKVStorage hook

Starting from v0.5.5, thanks to the power of JSI, we now have our very own useMMKVStorage Hook. Think of it like a persisted state that will always write every change in storage and update your app UI instantly. It doesn't matter if you reload the app or restart it.

import { MMKVLoader, useMMKVStorage } from 'react-native-mmkv-storage';

const storage = new MMKVLoader().initialize();
const App = () => {
  const [user, setUser] = useMMKVStorage('user', storage, 'robert');
  const [age, setAge] = useMMKVStorage('age', storage, 24);

  return (
    <View style={styles.header}>
      <Text style={styles.headerText}>
        I am {user} and I am {age} years old.
      </Text>
    </View>
  );
};

Learn more about useMMKVStorage hook it in the docs.

useIndex hook

A hook that will take an array of keys and returns an array of values for those keys. This is supposed to work in combination with Transactions. When you have build your custom index, you will need an easy and quick way to load values for your index. useIndex hook actively listens to all read/write changes and updates the values accordingly.

const App = () => {
    // Get list of all post ids
    const postsIndex = useMMKVStorage("postsIndex",storage,[]); // ['post123','post234'];
    // Get the posts based on those ids.
    const [posts,update,remove] = useIndex(postsIndex,"object" storage);

    return <View>
    <FlatList
    data={posts}
    renderItem={...}
    >
</View>

}

Learn more about useIndex hook it in the docs.

Lifecycle Control with Transaction Manager

Listen to a value's lifecycle and mutate it on the go. Transactions lets you register lifecycle functions with your storage instance such as Read, Write and Delete. This allows for a better and more managed control over the storage and also let's you build custom indexes with a few lines of code.

MMKV.transactions.register('object', 'beforewrite', ({ key, value }) => {
  if (key.startsWith('post.')) {
    // Call this only when the key has the post prefix.
    let indexForTag = MMKV.getArray(`${value.tag}-index`) || [];
    MMKV.setArray(indexForTag.push(key));
  }
});

Learn more about how to use Transactions in docs

Multi-Process Support

MMKV supports concurrent read-read and read-write access between processes. This means that you can use MMKV for various extensions and widgets and your app.

Create unlimited Database instances

You can create many database instances. This helps greatly if you have separate logics/modules in the same app that use data differently, It also helps in better performance since each database instance is small instead of a single bulky database which makes things slower as it grows.

const userStorage = new MMKVLoader().withEncryption().withInstanceID('userdata').initialize();

const settingsStorage = new MMKVLoader().withInstanceID('settings').initialize();

Full encryption support

The library supports full encryption (AES CFB-128) on Android and iOS. You can choose to store your encryption key securely for continuious usage. The library uses Keychain on iOS and Android Keystore on android (API 23 and above). Encrypting an instance is simple:

const storage = new MMKVLoader()
  .withEncryption() // Generates a random key and stores it securely in Keychain
  .initialize();

And that's it.

Simple indexer and data querying

For each database instance, there is one global key index and then there are indexes of each type of data. So querying is easy and fast.

Supports redux-persist

Support for redux persist is also added starting from v0.3.2.

Supports expo

You can use this library with expo bare workflow.

Flipper plugin

Thanks to pnthach95 Flipper plugin is finally here. https://github.com/pnthach95/flipper-plugin-react-native-mmkv-storage. It supports logging and manipulating storage values on the fly.

Consider supporting with a ⭐️ star on GitHub

If you are using the library in one of your projects, consider supporting with a star. It takes a lot of time and effort to keep this maintained and address issues and bugs. Thank you.

Contact & Support

  • Create a GitHub issue for bug reports, feature requests, or questions
  • Follow @ammarahm-ed

I want to contribute

That is awesome news! There is a lot happening at a very fast pace in this library right now. Every little help is precious. You can contribute in many ways:

  • Suggest code improvements on native iOS and Android
  • If you have suggestion or idea you want to discuss, open an issue.
  • Open an issue if you want to make a pull request, and tell me what you want to improve or add so we can discuss
  • I am always open to new ideas

Special thanks to

License

This library is licensed under the MIT license.

Copyright © Ammar Ahmed (@ammarahm-ed)

Notesnook Logo

react-native-mmkv-storage's People

Contributors

ammarahm-ed avatar ayush-shta avatar bill2004158 avatar cdaleas avatar douugdev avatar dysphoricunicorn avatar focux avatar hatem-72 avatar jeneavranceanu avatar jonivr avatar laffed avatar mateosilguero avatar michaelvilleneuve avatar mmapplebeck avatar mmmoussa avatar mookiies avatar netshade avatar normanzb avatar optinify-andrei avatar pfcodes avatar pnthach95 avatar polishchlieb avatar r0b0t3d avatar retyui avatar robinsoncol avatar saltedblowfish avatar theyurig avatar tony-sanchez avatar yunusemredilber avatar zfanta avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

react-native-mmkv-storage's Issues

initialize method does not return a promise

In the docs loaderclass.md, it suggests that the initialize method returns a promise that resolves with the API instance.
But this is not reflected in the index.d.ts file. The typescript file suggests that this method is synchronous so either the ts module is incorrect or the docs are incorrect.

I've made a PR correcting the docs.

What happens if saving is interrupted/corrupted?

Currently, I am doing:

await this.MmkvInfo.setBoolAsync(MmkvInfoIsSavingKey, true);
await this.MmkvInfo.setArrayAsync(MmkvInfoArrayKey, this.infoArray);
await this.MmkvInfo.setBoolAsync(MmkvInfoIsSavingKey, false);

and on the code start, I check if the MmkvInfoIsSavingKey isn't false. Not being false, I consider that the saving failed, and I wipe all the corresponding data.

But, is it needed? Does the MMKV already do something like this?

FR: Biometric auth

In order to cover every scenario we've been asked to secure storage against a fingerprint unlock to prevent accessing data from an unlocked phone.

Previous secured storage libraries I'd used allowed this, I think it would make sense for a library like this to support that.

The only other way I could see this working is using two libraries, one just to generate and retrieve the encryption key with this library.

Add fallback value if data doesn't exist

Instead of having to wrapping with try/catches, the .getXYZ sync or async should have another parameter of options, having it the prop of fallback, to use it if the value doesn't exists, instead of throwing "Value for key does not exist"

Roadmap

The great thing about MMKV is that its very simple and easy to use. Also it is very fast, so I am thinking of maintaining this library here in long term which means if you are using it you dont have to worry because I will be fixing things on the way. So here is the list of things that need to be implemented if someone is interested in contributing.

v0.3.0

  • Support to set int and boolean data types.
  • Encryption
  • Create unlimited instances of database, for example, an encrypted instance with everything important and a normal one such as app settings or something that you are storing.
  • Data type Indexer
  • Rewrite docs using docsify.
  • Add some optimizations to give further performance boost

v0.5.0

  • Rewrite using JSI without Java/ObjC Bridge
  • 0.001s read/write

next v0.5.5

  • Make the lib reactive to changes using Hooks & Event Listeners
  • add redux-persist support
  • Synchronous initialization
  • Add Test Coverage

iOS crashing using encryption on 0.3.5

The library currently does not seem to work with encryption.

2020-07-18 16:13:45.028175+0100 TheApp[4657:690803] [javascript] 'STORAGE', 'SET OBJECT', '2', { data: [Getter/Setter] }
Assertion failed: (data.m_data == nil), function KeyValueHolderCrypt, file /Users/kyle/ssg-frontend-boilerplate/mobile/ios/Pods/MMKVCore/Core/KeyValueHolder.cpp, line 69.

Reproduction

 MMKV = new MMKVStorage.Loader()
        // uncommenting this breaks the app
        // .withEncryption()
        .initialize();

Version 0.3.5 can't get encrypted data, but version 0.3.2 can

Reproduce on Android, untest on iOS:

  • Clone my example, make sure react-native-mmkv-storage version is 0.3.5
  • Run project
  • Enter username and password, check Save data
  • Press Log in
  • If you see Login success, kill app
  • Open app and expect username and password in TextInputs but no
  • Install version 0.3.2 and run project => Username and password show up

Can not co-existence with react-native-keychain

Tested on react-native version 0.63.2

I already use react-native-keychain in our project and we've been really happy with that.

But now I am looking in to the possibility of backing my Apollo (graphql) cache with react-native-mmkv-storage but I get a compilation error on iOS:

duplicate symbol '_accessibleValue' in 
> libRNKeychain.a(RNKeychainManager.o)
> libreact-native-mmkv-storage.a(SecureStorage.o)

Something that has come up before or do you have any solution to it?

View database data

It would be nice if you could add a method to view all keys / entries currently present in the database

Warning Require cycle: node_modules/react-native-mmkv-storage/index.js

I've instaled lib ( "react-native-mmkv-storage": "^0.3.0", ) and first that I've notice when I use it in my code is

Require cycle: node_modules/react-native-mmkv-storage/index.js -> node_modules/react-native-mmkv-storage/src/loader.js -> node_modules/react-native-mmkv-storage/index.js

Require cycles are allowed, but can result in uninitialized values. Consider refactoring to remove the need for a cycle.

Screenshot from 2020-04-11 08-15-50

I think this is something that should fixed and you may need to know

BTW. Great work with this library! Thank you!

[iOS] UI API called from background thread Group

version: "0.3.2",

[UIApplication applicationState] must be used from main thread only
file: libMMKV.mm
method: + (void)initialize

auto appState = [UIApplication sharedApplication].applicationState;

stacktrace:

#0	0x00000001088fc40a in +[MMKV initialize] at /Users/bill/Projects/mattermost/ios/Pods/MMKV/iOS/MMKV/MMKV/libMMKV.mm:72
#1	0x00007fff50b98103 in CALLING_SOME_+initialize_METHOD ()
#2	0x00007fff50b98ee9 in initializeNonMetaClass ()
#3	0x00007fff50b994ba in initializeAndMaybeRelock(objc_class*, objc_object*, mutex_tt<false>&, bool) ()
#4	0x00007fff50ba3a5d in lookUpImpOrForward ()
#5	0x00007fff50b94219 in _objc_msgSend_uncached ()
#6	0x0000000108f7d036 in -[MMKVStorage init] at /Users/bill/Projects/mattermost/node_modules/react-native-mmkv-storage/ios/MMKVStorage.m:50
#7	0x0000000108a62254 in __44-[RCTModuleData initWithModuleClass:bridge:]_block_invoke at /Users/bill/Projects/mattermost/node_modules/react-native/React/Base/RCTModuleData.mm:77
#8	0x0000000108a62c26 in -[RCTModuleData setUpInstanceAndBridge] at /Users/bill/Projects/mattermost/node_modules/react-native/React/Base/RCTModuleData.mm:124
#9	0x0000000108a64d0b in -[RCTModuleData instance] at /Users/bill/Projects/mattermost/node_modules/react-native/React/Base/RCTModuleData.mm:298
#10	0x0000000108a6552a in -[RCTModuleData methodQueue] at /Users/bill/Projects/mattermost/node_modules/react-native/React/Base/RCTModuleData.mm:353
#11	0x0000000108a72bf1 in facebook::react::RCTNativeModule::invoke(unsigned int, folly::dynamic&&, int) at /Users/bill/Projects/mattermost/node_modules/react-native/React/CxxModule/RCTNativeModule.mm:76
#12	0x0000000108c1f95c in facebook::react::ModuleRegistry::callNativeMethod(unsigned int, unsigned int, folly::dynamic&&, int) at /Users/bill/Projects/mattermost/node_modules/react-native/ReactCommon/cxxreact/ModuleRegistry.cpp:159
#13	0x0000000108c31e3b in facebook::react::JsToNativeBridge::callNativeModules(facebook::react::JSExecutor&, folly::dynamic&&, bool) at /Users/bill/Projects/mattermost/node_modules/react-native/ReactCommon/cxxreact/NativeToJsBridge.cpp:60
#14	0x0000000108c69087 in facebook::react::JSIExecutor::callNativeModules(facebook::jsi::Value const&, bool) at /Users/bill/Projects/mattermost/node_modules/react-native/ReactCommon/jsiexecutor/jsireact/JSIExecutor.cpp:309
#15	0x0000000108c701fd in facebook::react::JSIExecutor::loadApplicationScript(std::__1::unique_ptr<facebook::react::JSBigString const, std::__1::default_delete<facebook::react::JSBigString const> >, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >)::$_1::operator()(facebook::jsi::Runtime&, facebook::jsi::Value const&, facebook::jsi::Value const*, unsigned long) const at /Users/bill/Projects/mattermost/node_modules/react-native/ReactCommon/jsiexecutor/jsireact/JSIExecutor.cpp:101
#16	0x0000000108c70146 in decltype(std::__1::forward<facebook::react::JSIExecutor::loadApplicationScript(std::__1::unique_ptr<facebook::react::JSBigString const, std::__1::default_delete<facebook::react::JSBigString const> >, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >)::$_1&>(fp)(std::__1::forward<facebook::jsi::Runtime&>(fp0), std::__1::forward<facebook::jsi::Value const&>(fp0), std::__1::forward<facebook::jsi::Value const*>(fp0), std::__1::forward<unsigned long>(fp0))) std::__1::__invoke<facebook::react::JSIExecutor::loadApplicationScript(std::__1::unique_ptr<facebook::react::JSBigString const, std::__1::default_delete<facebook::react::JSBigString const> >, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >)::$_1&, facebook::jsi::Runtime&, facebook::jsi::Value const&, facebook::jsi::Value const*, unsigned long>(facebook::react::JSIExecutor::loadApplicationScript(std::__1::unique_ptr<facebook::react::JSBigString const, std::__1::default_delete<facebook::react::JSBigString const> >, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >)::$_1&, facebook::jsi::Runtime&, facebook::jsi::Value const&, facebook::jsi::Value const*&&, unsigned long&&) at /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include/c++/v1/type_traits:4425
#17	0x0000000108c70093 in facebook::jsi::Value std::__1::__invoke_void_return_wrapper<facebook::jsi::Value>::__call<facebook::react::JSIExecutor::loadApplicationScript(std::__1::unique_ptr<facebook::react::JSBigString const, std::__1::default_delete<facebook::react::JSBigString const> >, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >)::$_1&, facebook::jsi::Runtime&, facebook::jsi::Value const&, facebook::jsi::Value const*, unsigned long>(facebook::react::JSIExecutor::loadApplicationScript(std::__1::unique_ptr<facebook::react::JSBigString const, std::__1::default_delete<facebook::react::JSBigString const> >, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >)::$_1&, facebook::jsi::Runtime&, facebook::jsi::Value const&, facebook::jsi::Value const*&&, unsigned long&&) at /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include/c++/v1/__functional_base:317
#18	0x0000000108c6ffc3 in std::__1::__function::__alloc_func<facebook::react::JSIExecutor::loadApplicationScript(std::__1::unique_ptr<facebook::react::JSBigString const, std::__1::default_delete<facebook::react::JSBigString const> >, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >)::$_1, std::__1::allocator<facebook::react::JSIExecutor::loadApplicationScript(std::__1::unique_ptr<facebook::react::JSBigString const, std::__1::default_delete<facebook::react::JSBigString const> >, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >)::$_1>, facebook::jsi::Value (facebook::jsi::Runtime&, facebook::jsi::Value const&, facebook::jsi::Value const*, unsigned long)>::operator()(facebook::jsi::Runtime&, facebook::jsi::Value const&, facebook::jsi::Value const*&&, unsigned long&&) at /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include/c++/v1/functional:1533
#19	0x0000000108c6ec95 in std::__1::__function::__func<facebook::react::JSIExecutor::loadApplicationScript(std::__1::unique_ptr<facebook::react::JSBigString const, std::__1::default_delete<facebook::react::JSBigString const> >, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >)::$_1, std::__1::allocator<facebook::react::JSIExecutor::loadApplicationScript(std::__1::unique_ptr<facebook::react::JSBigString const, std::__1::default_delete<facebook::react::JSBigString const> >, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >)::$_1>, facebook::jsi::Value (facebook::jsi::Runtime&, facebook::jsi::Value const&, facebook::jsi::Value const*, unsigned long)>::operator()(facebook::jsi::Runtime&, facebook::jsi::Value const&, facebook::jsi::Value const*&&, unsigned long&&) at /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include/c++/v1/functional:1707
#20	0x0000000108c58126 in std::__1::__function::__value_func<facebook::jsi::Value (facebook::jsi::Runtime&, facebook::jsi::Value const&, facebook::jsi::Value const*, unsigned long)>::operator()(facebook::jsi::Runtime&, facebook::jsi::Value const&, facebook::jsi::Value const*&&, unsigned long&&) const at /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include/c++/v1/functional:1860
#21	0x0000000108c57a9e in std::__1::function<facebook::jsi::Value (facebook::jsi::Runtime&, facebook::jsi::Value const&, facebook::jsi::Value const*, unsigned long)>::operator()(facebook::jsi::Runtime&, facebook::jsi::Value const&, facebook::jsi::Value const*, unsigned long) const at /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include/c++/v1/functional:2419
#22	0x0000000108c57172 in facebook::jsc::JSCRuntime::createFunctionFromHostFunction(facebook::jsi::PropNameID const&, unsigned int, std::__1::function<facebook::jsi::Value (facebook::jsi::Runtime&, facebook::jsi::Value const&, facebook::jsi::Value const*, unsigned long)>)::HostFunctionMetadata::call(OpaqueJSContext const*, OpaqueJSValue*, OpaqueJSValue*, unsigned long, OpaqueJSValue const* const*, OpaqueJSValue const**) at /Users/bill/Projects/mattermost/node_modules/react-native/ReactCommon/jsi/JSCRuntime.cpp:1106
#23	0x00007fff26a62a8c in JSC::JSCallbackObject<JSC::JSDestructibleObject>::call(JSC::ExecState*) ()
#24	0x00007fff26ec9300 in JSC::handleHostCall(JSC::ExecState*, JSC::JSValue, JSC::CallLinkInfo*) ()
#25	0x00007fff26ec8d87 in operationLinkCall ()
#26	0x00003d3342001727 in 0x3d3342001727 ()
#27	0x00003d33420d8000 in 0x3d33420d8000 ()
#28	0x00003d33420d3f20 in 0x3d33420d3f20 ()
#29	0x00007fff26a29bb3 in llint_entry ()
#30	0x00007fff26a29bb3 in llint_entry ()
#31	0x00003d33420e6f34 in 0x3d33420e6f34 ()
#32	0x00007fff26a29b33 in llint_entry ()
#33	0x00003d33420eaca7 in 0x3d33420eaca7 ()
#34	0x00007fff26a29b33 in llint_entry ()
#35	0x00007fff26a29bb3 in llint_entry ()
#36	0x00007fff26a29bb3 in llint_entry ()
#37	0x00007fff26a29b33 in llint_entry ()
#38	0x00003d33420e1aee in 0x3d33420e1aee ()
#39	0x00007fff26a2a6f1 in llint_entry ()
#40	0x00007fff26a29bb3 in llint_entry ()
#41	0x00007fff26a29b33 in llint_entry ()
#42	0x00007fff26a29bb3 in llint_entry ()
#43	0x00007fff26a29bb3 in llint_entry ()
#44	0x00007fff26a29b33 in llint_entry ()
#45	0x00007fff26a29b33 in llint_entry ()
#46	0x00007fff26a29b33 in llint_entry ()
#47	0x00007fff26a29bb3 in llint_entry ()
#48	0x00003d33420e6f34 in 0x3d33420e6f34 ()
#49	0x00007fff26a29b33 in llint_entry ()
#50	0x00003d33420e6f34 in 0x3d33420e6f34 ()
#51	0x00007fff26a29b33 in llint_entry ()
#52	0x00007fff26a29bb3 in llint_entry ()
#53	0x00007fff26a29bb3 in llint_entry ()
#54	0x00007fff26a29b33 in llint_entry ()
#55	0x00003d33420e1aee in 0x3d33420e1aee ()
#56	0x00007fff26a2a6f1 in llint_entry ()
#57	0x00007fff26a29bb3 in llint_entry ()
#58	0x00007fff26a29b33 in llint_entry ()
#59	0x00007fff26a29bb3 in llint_entry ()
#60	0x00007fff26a29bb3 in llint_entry ()
#61	0x00007fff26a29bb3 in llint_entry ()
#62	0x00007fff26a29bb3 in llint_entry ()
#63	0x00007fff26a29bb3 in llint_entry ()
#64	0x00007fff26a29bb3 in llint_entry ()
#65	0x00007fff26a29b33 in llint_entry ()
#66	0x00007fff26a29bb3 in llint_entry ()
#67	0x00007fff26a29b33 in llint_entry ()
#68	0x00007fff26a29bb3 in llint_entry ()
#69	0x00007fff26a29bb3 in llint_entry ()
#70	0x00007fff26a29b33 in llint_entry ()
#71	0x00007fff26a29bb3 in llint_entry ()
#72	0x00007fff26a29b33 in llint_entry ()
#73	0x00007fff26a29b33 in llint_entry ()
#74	0x00003d3342011bd6 in 0x3d3342011bd6 ()
#75	0x00007fff26a29b33 in llint_entry ()
#76	0x00007fff26a29b33 in llint_entry ()
#77	0x00007fff26a29bb3 in llint_entry ()
#78	0x00007fff26a29b33 in llint_entry ()
#79	0x00003d334200ec36 in 0x3d334200ec36 ()
#80	0x00007fff26a12ddf in vmEntryToJavaScript ()
#81	0x00007fff26e295f0 in JSC::Interpreter::executeCall(JSC::ExecState*, JSC::JSObject*, JSC::CallType, JSC::CallData const&, JSC::JSValue, JSC::ArgList const&) ()
#82	0x00007fff27076a6b in JSC::call(JSC::ExecState*, JSC::JSValue, JSC::CallType, JSC::CallData const&, JSC::JSValue, JSC::ArgList const&) ()
#83	0x00007fff2710f10a in JSC::boundThisNoArgsFunctionCall(JSC::ExecState*) ()
#84	0x00007fff26a12f06 in vmEntryToNative ()
#85	0x00007fff26e29637 in JSC::Interpreter::executeCall(JSC::ExecState*, JSC::JSObject*, JSC::CallType, JSC::CallData const&, JSC::JSValue, JSC::ArgList const&) ()
#86	0x00007fff27076bd4 in JSC::profiledCall(JSC::ExecState*, JSC::ProfilingReason, JSC::JSValue, JSC::CallType, JSC::CallData const&, JSC::JSValue, JSC::ArgList const&) ()
#87	0x00007fff26a70438 in JSObjectCallAsFunction ()
#88	0x0000000108c4f391 in facebook::jsc::JSCRuntime::call(facebook::jsi::Function const&, facebook::jsi::Value const&, facebook::jsi::Value const*, unsigned long) at /Users/bill/Projects/mattermost/node_modules/react-native/ReactCommon/jsi/JSCRuntime.cpp:1208
#89	0x0000000108c5e9c6 in facebook::jsi::Function::call(facebook::jsi::Runtime&, facebook::jsi::Value const*, unsigned long) const at /Users/bill/Projects/mattermost/ios/Pods/Headers/Private/React-jsi/jsi/jsi-inl.h:224
#90	0x0000000108c5e904 in facebook::jsi::Function::call(facebook::jsi::Runtime&, std::initializer_list<facebook::jsi::Value>) const at /Users/bill/Projects/mattermost/ios/Pods/Headers/Private/React-jsi/jsi/jsi-inl.h:229
#91	0x0000000108c694ab in facebook::jsi::Value facebook::jsi::Function::call<double const&, facebook::jsi::Value>(facebook::jsi::Runtime&, double const&, facebook::jsi::Value&&) const at /Users/bill/Projects/mattermost/ios/Pods/Headers/Public/React-jsi/jsi/jsi-inl.h:237
#92	0x0000000108c691e2 in facebook::react::JSIExecutor::invokeCallback(double, folly::dynamic const&) at /Users/bill/Projects/mattermost/node_modules/react-native/ReactCommon/jsiexecutor/jsireact/JSIExecutor.cpp:241
#93	0x0000000108c39ad7 in facebook::react::NativeToJsBridge::invokeCallback(double, folly::dynamic&&)::$_2::operator()(facebook::react::JSExecutor*) const at /Users/bill/Projects/mattermost/node_modules/react-native/ReactCommon/cxxreact/NativeToJsBridge.cpp:218
#94	0x0000000108c399a2 in decltype(std::__1::forward<facebook::react::NativeToJsBridge::invokeCallback(double, folly::dynamic&&)::$_2&>(fp)(std::__1::forward<facebook::react::JSExecutor*>(fp0))) std::__1::__invoke<facebook::react::NativeToJsBridge::invokeCallback(double, folly::dynamic&&)::$_2&, facebook::react::JSExecutor*>(facebook::react::NativeToJsBridge::invokeCallback(double, folly::dynamic&&)::$_2&, facebook::react::JSExecutor*&&) at /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include/c++/v1/type_traits:4425
#95	0x0000000108c39942 in void std::__1::__invoke_void_return_wrapper<void>::__call<facebook::react::NativeToJsBridge::invokeCallback(double, folly::dynamic&&)::$_2&, facebook::react::JSExecutor*>(facebook::react::NativeToJsBridge::invokeCallback(double, folly::dynamic&&)::$_2&, facebook::react::JSExecutor*&&) at /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include/c++/v1/__functional_base:348
#96	0x0000000108c39902 in std::__1::__function::__alloc_func<facebook::react::NativeToJsBridge::invokeCallback(double, folly::dynamic&&)::$_2, std::__1::allocator<facebook::react::NativeToJsBridge::invokeCallback(double, folly::dynamic&&)::$_2>, void (facebook::react::JSExecutor*)>::operator()(facebook::react::JSExecutor*&&) at /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include/c++/v1/functional:1533
#97	0x0000000108c38633 in std::__1::__function::__func<facebook::react::NativeToJsBridge::invokeCallback(double, folly::dynamic&&)::$_2, std::__1::allocator<facebook::react::NativeToJsBridge::invokeCallback(double, folly::dynamic&&)::$_2>, void (facebook::react::JSExecutor*)>::operator()(facebook::react::JSExecutor*&&) at /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include/c++/v1/functional:1707
#98	0x0000000108c42c9d in std::__1::__function::__value_func<void (facebook::react::JSExecutor*)>::operator()(facebook::react::JSExecutor*&&) const at /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include/c++/v1/functional:1860
#99	0x0000000108c42c20 in std::__1::function<void (facebook::react::JSExecutor*)>::operator()(facebook::react::JSExecutor*) const at /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include/c++/v1/functional:2419
#100	0x0000000108c42be8 in facebook::react::NativeToJsBridge::runOnExecutorQueue(std::__1::function<void (facebook::react::JSExecutor*)>)::$_7::operator()() const at /Users/bill/Projects/mattermost/node_modules/react-native/ReactCommon/cxxreact/NativeToJsBridge.cpp:290
#101	0x0000000108c42b5d in decltype(std::__1::forward<facebook::react::NativeToJsBridge::runOnExecutorQueue(std::__1::function<void (facebook::react::JSExecutor*)>)::$_7&>(fp)()) std::__1::__invoke<facebook::react::NativeToJsBridge::runOnExecutorQueue(std::__1::function<void (facebook::react::JSExecutor*)>)::$_7&>(facebook::react::NativeToJsBridge::runOnExecutorQueue(std::__1::function<void (facebook::react::JSExecutor*)>)::$_7&) at /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include/c++/v1/type_traits:4425
#102	0x0000000108c42b0d in void std::__1::__invoke_void_return_wrapper<void>::__call<facebook::react::NativeToJsBridge::runOnExecutorQueue(std::__1::function<void (facebook::react::JSExecutor*)>)::$_7&>(facebook::react::NativeToJsBridge::runOnExecutorQueue(std::__1::function<void (facebook::react::JSExecutor*)>)::$_7&) at /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include/c++/v1/__functional_base:348
#103	0x0000000108c42add in std::__1::__function::__alloc_func<facebook::react::NativeToJsBridge::runOnExecutorQueue(std::__1::function<void (facebook::react::JSExecutor*)>)::$_7, std::__1::allocator<facebook::react::NativeToJsBridge::runOnExecutorQueue(std::__1::function<void (facebook::react::JSExecutor*)>)::$_7>, void ()>::operator()() at /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include/c++/v1/functional:1533
#104	0x0000000108c4163e in std::__1::__function::__func<facebook::react::NativeToJsBridge::runOnExecutorQueue(std::__1::function<void (facebook::react::JSExecutor*)>)::$_7, std::__1::allocator<facebook::react::NativeToJsBridge::runOnExecutorQueue(std::__1::function<void (facebook::react::JSExecutor*)>)::$_7>, void ()>::operator()() at /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include/c++/v1/functional:1707
#105	0x0000000108a27685 in std::__1::__function::__value_func<void ()>::operator()() const at /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include/c++/v1/functional:1860
#106	0x0000000108a26d45 in std::__1::function<void ()>::operator()() const at /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include/c++/v1/functional:2419
#107	0x0000000108a26ab8 in facebook::react::tryAndReturnError(std::__1::function<void ()> const&) at /Users/bill/Projects/mattermost/node_modules/react-native/React/CxxModule/RCTCxxUtils.mm:72
#108	0x0000000108a55a11 in facebook::react::RCTMessageThread::tryFunc(std::__1::function<void ()> const&) at /Users/bill/Projects/mattermost/node_modules/react-native/React/CxxBridge/RCTMessageThread.mm:59
#109	0x0000000108a5af33 in facebook::react::RCTMessageThread::runOnQueue(std::__1::function<void ()>&&)::$_1::operator()() const at /Users/bill/Projects/mattermost/node_modules/react-native/React/CxxBridge/RCTMessageThread.mm:72
#110	0x0000000108a5aebd in decltype(std::__1::forward<facebook::react::RCTMessageThread::runOnQueue(std::__1::function<void ()>&&)::$_1&>(fp)()) std::__1::__invoke<facebook::react::RCTMessageThread::runOnQueue(std::__1::function<void ()>&&)::$_1&>(facebook::react::RCTMessageThread::runOnQueue(std::__1::function<void ()>&&)::$_1&) at /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include/c++/v1/type_traits:4425
#111	0x0000000108a5ae6d in void std::__1::__invoke_void_return_wrapper<void>::__call<facebook::react::RCTMessageThread::runOnQueue(std::__1::function<void ()>&&)::$_1&>(facebook::react::RCTMessageThread::runOnQueue(std::__1::function<void ()>&&)::$_1&) at /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include/c++/v1/__functional_base:348
#112	0x0000000108a5ae3d in std::__1::__function::__alloc_func<facebook::react::RCTMessageThread::runOnQueue(std::__1::function<void ()>&&)::$_1, std::__1::allocator<facebook::react::RCTMessageThread::runOnQueue(std::__1::function<void ()>&&)::$_1>, void ()>::operator()() at /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include/c++/v1/functional:1533
#113	0x0000000108a5999e in std::__1::__function::__func<facebook::react::RCTMessageThread::runOnQueue(std::__1::function<void ()>&&)::$_1, std::__1::allocator<facebook::react::RCTMessageThread::runOnQueue(std::__1::function<void ()>&&)::$_1>, void ()>::operator()() at /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include/c++/v1/functional:1707
#114	0x0000000108a27685 in std::__1::__function::__value_func<void ()>::operator()() const at /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include/c++/v1/functional:1860
#115	0x0000000108a26d45 in std::__1::function<void ()>::operator()() const at /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include/c++/v1/functional:2419
#116	0x0000000108a5577c in ___ZN8facebook5react16RCTMessageThread8runAsyncENSt3__18functionIFvvEEE_block_invoke at /Users/bill/Projects/mattermost/node_modules/react-native/React/CxxBridge/RCTMessageThread.mm:39
#117	0x00007fff23bb204c in __CFRUNLOOP_IS_CALLING_OUT_TO_A_BLOCK__ ()
#118	0x00007fff23bb17b8 in __CFRunLoopDoBlocks ()
#119	0x00007fff23bacbcb in __CFRunLoopRun ()
#120	0x00007fff23babe16 in CFRunLoopRunSpecific ()
#121	0x00000001089f6331 in +[RCTCxxBridge runRunLoop] at /Users/bill/Projects/mattermost/node_modules/react-native/React/CxxBridge/RCTCxxBridge.mm:269
#122	0x00007fff257617b7 in __NSThread__start__ ()
#123	0x00007fff51c04109 in _pthread_start ()
#124	0x00007fff51bffb8b in thread_start ()

ref:
mattermost/mattermost-mobile#4505

[bug] indexer crashes on ios

On ios when running await storage.indexer.maps.getAll() it crashes if there is nothing saved before instead of returning [] while android is working as expected.

Even with try/catch, it's crashing anyway.

Nested object is not working

image

     const MMKV = await new MMKVStorage.Loader().withEncryption().initialize();

      let settings = {
        ...currentState.settings,
        themes: {name: newState.name},
      };
      // {"proxy": "On Demand", "server": "https://serve.xxxxxxxxx.com", "themes": {"name": "dark"}}
      MMKV.setMapAsync('settings', settings);

setArrayAsync is freezing array items forever

After some hours (I was thinking it was a React problem) trying to find an immutable error in my code (= trying to change a frozen object), I found the error. Looks like the setArrayAsync is freezing each item of the array, and they aren't then being unfrozen.

e.g.:

console.log('isFrozen 1: ', Object.isFrozen(this.infoArray), Object.isFrozen(this.infoArray[0]));
await this.MmkvInfo.setArrayAsync(MmkvInfoArrayKey, this.infoArray);
console.log('isFrozen 2: ', Object.isFrozen(this.infoArray), Object.isFrozen(this.infoArray[0]));

This will print false, false and then false, true.

It makes sense that the given data is frozen (so, the data won't be changed while being saved), but, they aren't being unfrozen.

Android RAM <= 2.0 GB Throws Error

Thanks for the library. Had issues with users in production that have RAM <= 2.0GB.

After getting hold of an Android phone with 2.0GB RAM, I debugged the issue.

I learnt that the methods from the mmkv library produce the following error:
"Wrong password or storage corrupt"

Is there a requirement that I missed? Can this library accommodate users with RAM <= 2.0GB?

Cheers!

Retrieve all storage

Hi it's possible to get all storage ? I wish hydrate a store on load, so there are a function like .get() for retrieve all key in a loader ?

Thanks

Running slower than Async Storage but only for set/getObject

Please let me know if I'm doing something wrong here, however..

My intension would be to use this for local storage app state, almost certainly always with encryption.

However, even without encryption I'm seeing consistent performance deficit over the standard AsyncStorage library, my understanding is that maybe this might be faster?

https://github.com/kyle-ssg/mmkv-performance

Average results on iPhone XR

MMKV 63ms
Async Storage 18ms

Package Name?

I'm looking at using this as an alternative to react-native-sensitive-info.
Would you say this could be a good secure alternative once the encryption supports in?
Also i noticed the package name you are using is the same as the fast-storage module that you used as a base, any reason for not changing it?

Persist storage

Hi,

I was wondering if react-native-mmkv-storage is backing up the data. Because when I close the app, the data (ex: user data) that I set in mmkv storage is gone. I know the plugin uses memory to store data but how to persist because in my case I am not using redux. Also the data is often very large in terms of size.

thank you in advance

[0.5.2][IOS] Use of undeclared identifier 'kindOf'

When i run app in release mode on real device getting the following error:

/Users/nghia/Desktop/workingSpace/RNClientApp/ios/Pods/Headers/Public/React-jsi/jsi/jsi.h:933:43: Use of undeclared identifier 'kindOf'
/Users/nghia/Desktop/workingSpace/RNClientApp/node_modules/react-native-mmkv-storage/ios/MMKVNative.mm:2:9: In file included from /Users/nghia/Desktop/workingSpace/RNClientApp/node_modules/react-native-mmkv-storage/ios/MMKVNative.mm:2:

RN:0.63.4
OS: MacOS

Make Initialization Synchronous

The current initialization of MMKV Instances is async. This is leading problems such as when you want to initialize the instance at the very beginning of the your app. One such case is redux-persist. In such a situation the best way is to make initialization synchronous.

FR: Potential for secured storage?

I'd love to start trying this out, however one requirement we have on almost all of our projects requiring PEN testing is for all data to be encrypted either through standard keystore, and potentially an access control like pin/biometrics.

This leads us to using an approach quite similar to https://www.npmjs.com/package/react-native-secure-storage.

Is encrypted storage something that would / could be on the roadmap?

[0.5.2][Expo + Android] global.getStringMMKV is not a function

react-native 0.63.2
react-native-mmkv-storage 0.5.2

My code :

const Storage = new MMKVStorage.Loader().initialize()

The error :

TypeError: global.getStringMMKV is not a function. (In 'global.getStringMMKV(id, STORE_ID)', 'global.getStringMMKV' is undefined)

in src/mmkv/IDStore.js line 53 :

let storeUnit = global.getStringMMKV(id, STORE_ID);

Seems like global object is not initialized !
Is there a dependency i'm not aware of ?

Thanks for your help

Question about chat-like apps

Hey, just found out this package, nice one!

I am making a Message Logs system for my app, which works very similarly to a messaging app. I came to an issue that I hope someone can point me a faster solution than me creating a new from the scratch.

I will have a Flatlist to display the messages, and the messages may be added to the end of the array/object or somewhere in the middle, on demand if the client doesn't own it.

This package looks to solve part of my issue, but I still don't know how to handle the FlatList data, that may be really long. I want to have some sort of pagination, so I won't have a 10000 length array in the RAM and a long time to update it on new data fetched.

Does any one here have experience on that? Thanks!

Are multi object writes performant?

If I want to write 50 objects, like with

    const promises: Promise<any>[] = [];
    for (const params of paramsArray)
      promises.push(this.MmkvData.setMapAsync(params.logId, params.logData));

    await Promise.all(promises);

Does it have a good performance? Are the writes somehow "batched"? Or, if each write takes 10ms, it will take 500ms?

If not, could you add this functionality?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.