pouchdb live is a little too fast for realtime chat - vue.js

I am using the current vuex mutation to sync to my pouch/ couchdb which is excellent. However
As I am typing into text box I can type too fast and this can mean letters are not sent to sync, which is annoying but not a killer however if I edit in the middle and type at speed sometimes cursor will jump to the end, I want live as its live text but I would like to poll a little slower does anyone have any suggests.... there was a suggestion of using since : 'now' but that doesnt seem to slow it down
syncDB: () => {
pouchdb.replicate.from(remote).on('complete', function () {
store.commit('GET_ALL_NODES')
store.commit('GET_MY_NODES')
store.commit('GET_POSITIONS')
store.commit('GET_CONNECTIONS')
store.commit('GET_EMOJI')
// turn on two-way, continuous, retriable sync
pouchdb
.sync(remote, {
live: true,
retry: true,
attachments: true,
})
.on('change', function () {
// pop info into function to find out more
store.commit('GET_ALL_NODES')
store.commit('GET_MY_NODES')
store.commit('GET_POSITIONS')
store.commit('GET_CONNECTIONS')
store.commit('GET_EMOJI')
})
.on('paused', function () {
// replication paused (e.g. replication up to date, user went offline)
// console.log('replication paused')
})
.on('active', function () {
// replicate resumed (e.g. new changes replicating, user went back online)
//console.log('back active')
})
.on('denied', function () {
// a document failed to replicate (e.g. due to permissions)
})
.on('complete', function () {
// handle complete
})
.on('error', function (err) {
console.log(err)
})
})
},

I added a debounce via lodash to the text input which helps a lot it’s not perfect especially if you are editing in the middle of text but less jumps to the end and general start speedier typing isn’t an issue

Related

react-native-iap I have problem with successfully make a subscription payment

Have anyone successfully implemented in app subscriptions with react-native-iap in an app.
I have tried to implement it but still very unstable. Can't rely that the subscription payments work every time. Sometimes the pay dialog won't show, sometimes it won't continue, and so on. Its a problem on both android and iOS.
Short explanation on how I have implemented it:
When clicked on pay button after the user has selected the plan, for ex. monthly.
await requestSubscription({
sku: subscription.productId,
...(offerToken && { subscriptionOffers: [{sku: subscription.productId, offerToken}]}),
})
Then I have to listeners, currentPurchaseError and currentPurchase that is returned as a hook from the rniap library.
React.useEffect(() => {
const onError = async () => {
// Do something on error from rniap.
}
if (currentPurchaseError) {
onError()
}
}, [currentPurchaseError])
And
React.useEffect(() => {
const checkCurrentPurchase = async () => {
// Do something, this should trigger when a purchase is successful.
}
if (currentPurchase) {
checkCurrentPurchase()
}
}, [currentPurchase, finishTransaction])
My receipt validation is happening on our own backend and its worth mentioning that everything there is working.
As I asked, has anyone implemented this successfully. If so, how?
Or is it worth thinking of changing to like revenue cat?
rniap's documentation and example code is really small and right now I need some help.
/Alexander
I have tried to get a successful payment within iOS sandbox but with no luck.

Mongoose connection closing too soon before tests have run

I am a beginner using jest to test a node/express app with mongo database.
I am getting an issue where different tests are failing each time I run the tests and sometimes they all pass/all fail. I think it is because of a time-out or things not happening in the right order because I'm getting this error:
MongoPoolClosedError: Attempted to check out a connection from closed connection pool
a) can you let me know if you think I'm on the right track?
b) if so, is the solution to make this into an async function and how can I do that? (I have tried making it into async await, using .then and also putting the code that clears the database collections into the test files instead of the helper and have had no success so far.
beforeAll( (done) => {
mongoose.connect("mongodb://127.0.0.1/jobBuddy_test", {
useNewUrlParser: true,
useUnifiedTopology: true,
})
var db = mongoose.connection;
const users = db.collection('users')
users.deleteMany({})
const applications = db.collection('applications')
applications.deleteMany({})
db.on("error", console.error.bind(console, "MongoDB connection error:"));
db.on("open", function () {
done();
});
});
afterAll(function (done) {
mongoose.connection.close(true, function () {
done();
});
});

react-native how to remove persistence on firebase snapshot

I am little confused.
I am listening to firebase snapshot with sample code below
unsubscribe = firebase
.firestore()
.collection('collection')
.doc(id)
.onSnapshot(
function(doc) {
// other code
},
);
This will listen to the collection if there's new item for the specific id.
Then, closing the app will unsubscribe to the snapshot
useEffect(() => {
return () => {
if (unsubscribe) {
unsubscribe()
}
}
}, []);
It is working fine.
However, given the scenario.
If the snapshot triggered (eg. { value: 1 }) and then I closed the app.
Removed the value on the firebase for the specific id. (meaning the id should not received the item)
Re-open the app
I still get the previous value which is { value: 1} and then get the newest value which is undefined (since i removed the value)
Is the value persists on the app? How can I remove this one upon re-opening of the app?
Thanks!
From this answer:
There is now a feature in the API for clearing persistence. It is not recommended for anything but tests, but you can use
firebase.firestore().clearPersistence().catch(error => {
console.error('Could not enable persistence:', error.code);
})
It must run before the Firestore database is used.

How to minimize data traffic in vuejs

At work, we think about using Vuejs with Vuex for our frontend. I have already used it for private projects.
One of our big questions is the traffic. Our platform needs a lot of data, sometimes in large packages. Some of them are really big and it would be more expensive to load them more than once.
I've seen many examples of vue with vuex, but for me it looked like all the samples would request the same (already loaded) data every time they paged.
My real question is: Is there a way in vuejs or general to avoid or solve this problem? The only helpful thing I have found so far was this.
As far as I know, you can use this library https://github.com/kuitos/axios-extensions
An example here
import Axios from 'Axios';
import { throttleAdapterEnhancer } from 'axios-extensions';
const http = axios.create({
baseURL: '/',
headers: { 'Cache-Control': 'no-cache' },
adapter: throttleAdapterEnhancer(axios.defaults.adapter, { threshold: 2 * 1000 })
});
http.get('/users'); // make real http request
http.get('/users'); // responsed from the cache
http.get('/users'); // responsed from the cache
setTimeout(() => {
http.get('/users'); // after 2s, the real request makes again
}, 2 * 1000)
As you can see, you can create an adaptor and custom what you want. For example here, you keep the cache for only 2 seconds. So the first request to /users is a real one. The second and thirst request are cache, and the last one is after the two seconds, so it's a real one.
Can you be more specific about the context of how you will keep the cache. When do you need to reload the cache, after how many times, after which event, ...?
The strategy I use is to store the value on the Vuex state.
I write all my request in Vuex actions. In every action, I check if the data already exists on the Vuex state. If it does, I simply bypass the request and return the data from the state (saving requests from being called multiple times). If it doesn't exist, I'll make the request, then store the result on the Vuex state, and return the value.
Vuex Action:
getLists({ state, commit }) {
return new Promise((resolve, reject) => {
if (state.isSetLists === false) {
getListsFromServer((error, data) => {
if (error) {
reject(error);
} else {
console.log('call to getLists successful:', data);
commit('setLists', data.lists);
resolve(data.lists);
}
});
} else {
resolve(state.lists);
}
});
},
Then, the setLists mutation handles it like so:
setLists(state, lists) {
state.isSetLists = true;
state.lists = lists;
},
This way, the user can page around all they want, and only ever call each request once.

pouchdb + vuex update live with changes

I have an app that takes updates into VUEX store and syncs those change from pouchdb to couchdb. Which is great but now I need to have two clients connected and see the change in near realtime.
So I have the https://pouchdb.com/guides/changes.html API which I can use to listen for changes to the DB and when that happens call a action which mutates the vuex state on Client 2. Code below.
However the bit I cannot seem to work out is this code is not just listening all the time ? So where should I put this in Vue to ensure that it hears any changes. I can call it when I make a state change and I see that it hears the change but ofcourse I want to trigger a state change on client 2, without them having to make change. Do I need a timer ? The pouch docs seem to suggest this changes api should be able to update UI based on a change to the data, which I can probably call with a button press to check for changes ...but I want to listen in near realtime ?
pouchdb
.changes({
since: 'now',
include_docs: true
})
.on('change', function(change) {
// received a change
store.commit('CHANGE_STATE', change.doc.flavour)
})
.on('error', function(err) {
// handle errors
console.log(err)
})
Your explanation is a bit fuzzy in that you talk about client 2 without ever mentioning client 1. I assume client 2 is a passive listener and client 1 is where data is changed. If I remember correctly from when I was building my Vue / PouchDB project last year I looked into how to coordinate the Store and the Database, and then thought, "Why bother? They're just two kinds of local storage". As long as changes in client 1 replicate to your Couch server and client 2 detects those server side changes and writes them into reactive variables, they'll propagate to the UI.
I used replicate.to() for storing client-side changes and replicate.from() to detect server-side changes. The replicate() functions have their own timer, constantly monitoring the changes queue, so you don't need to roll your own.
This is what I ended up doing !
actions: {
SYNC_DB() {
// do one way, one-off sync from the server until completion
pouchdb.replicate.from(remote).on('complete', function(info) {
// then two-way, continuous, retriable sync
pouchdb
.sync(remote, { live: true, retry: true })
.on('change', function(info) {
store.commit('CHANGE_STATE', info.change.docs[0].flavour)
})
.on('paused', function(err) {
// replication paused (e.g. replication up to date, user went offline)
})
.on('active', function() {
// replicate resumed (e.g. new changes replicating, user went back online)
})
.on('denied', function(err) {
// a document failed to replicate (e.g. due to permissions)
})
.on('complete', function(info) {
// handle complete
})
.on('error', function(err) {
// handle error
})
})
},