Please report: Excessive number of pending callbacks: 2941 - react-native-firebase

I have this error "Please report: Excessive number of pending callbacks: 2941. Some pending callbacks that might have leaked by never being called from native code: ". It's because i try to read like 1400 documents in firestore. I do something like this:
array.map(userUid => {
var docRef = db.collection('users').doc(userUid);
docRef.get().then(doc => {
...
})
})
Here array is an array with 1400 users's uid. I don't know how to handle this error, do you have any idea ?
Infos:
react native: 0.61.1
react-native-firebase: 6.4.0
Bug on IOS simulator didn't try on Android.

Related

Redirect to a specific screen from React Native Firebase Push Notifications based on a Deeplink

I got a problem,
1 ) I'm using Firebase to send remote Push Notifications, i test by sending from FCM tester.
2 ) I've activated Deep-Linking in my project and started to use it.
3 ) In FCM tester i pass this key value into "notifications.data" :
{ "link" : "MY_LINK" }
Now i want my app to be able to recognize there is a deepLink in it & read it.
Which i achieved to do somehow but not the way i was looking for.
What i did :
NotificationContextProvider.ts
useEffect(() => {
const unsubscribeClosedApp = messaging().onNotificationOpenedApp(
remoteMessage => {
addNotification(remoteMessage);
console.log(
'Notification caused app to open from background state:',
remoteMessage.notification,
);
redirectFromKey(remoteMessage.data?.redirection);
console.log(remoteMessage.data, 'remote message data');
console.log(remoteMessage, 'remote message full');
console.log(remoteMessage.notification?.body, 'remote message body');
console.log(remoteMessage.notification?.title, 'remote message title');
if (remoteMessage.data?.link === 'https://[MY-LINK]/TnRV') {
console.log(remoteMessage.data?.link, 'Deeplink detected & opened');
navigation.navigate({
name: 'Logged',
params: {
screen: 'Onboarded',
params: {
screen: 'LastAnalyse',
},
},
});
}
},
);
And it's working fine but it's not based on reading a link, but by comparing a value and it's not what i'm trying to achieve.
Firebase Doc' give us a way to do this : https://rnfirebase.io/dynamic-links/usage#listening-for-dynamic-links
This is what Firebase suggests :
import dynamicLinks from '#react-native-firebase/dynamic-links';
function App() {
const handleDynamicLink = link => {
// Handle dynamic link inside your own application
if (link.url === 'https://invertase.io/offer') {
// ...navigate to your offers screen
}
};
useEffect(() => {
const unsubscribe = dynamicLinks().onLink(handleDynamicLink);
// When the component is unmounted, remove the listener
return () => unsubscribe();
}, []);
return null;
}
And i have no clue how to make it works.
I got to mention that deep-links are correctly setup in my project and working fine, my code is in Typescript.
Basicaly you can find on this web page what i'm trying to achieve but i want to use Firebase/messaging + Dynamic links. My project don't use local notifications and will never do : https://medium.com/tribalscale/working-with-react-navigation-v5-firebase-cloud-messaging-and-firebase-dynamic-links-7d5c817d50aa
Any idea ?
I looked into this earlier, it seems that...
You can't send a deep link in an FCM message using the firebase Compose Notification UI.
You probably can send a deep link in an FCM message using the FCM REST API. More in this stackoverflow post.
The REST API looks so cumbersome to implement you're probably better off the way you're doing it: Using the firebase message composer with a little data payload, and your app parses the message data with Invertase messaging methods firebase.messaging().getInitialNotification() and firebase.messaging().onNotificationOpenedApp().
As for deep linking, which your users might create in-app when trying to share something, or you might create in the firebase Dynamic Links UI: For your app to notice actual deep links being tapped on the device, you can use Invertase dynamic links methods firebase.dynamicLinks().getInitialLink() and firebase.dynamicLinks().onLink().

Firebase emulator always returns Error: 2 UNKNOWN after trying out the firestore background trigger functions?

** This is that my firestore (emulator) looks like**
I am trying to practice learning about cloud functions with firebase emulator however, I am running into this probably more often than I expected. I hope it is my end's problem.
I am trying to write a function where when the user made the https request to create an order, the background trigger function will return out the total (quantity * price) to the user. The later part is still WIP at the moment; I am currently just trying to understand and learn more about cloud functions.
This is the https request code I have to add the item, price, and quantity to my firestore. It works well and as intended.
exports.addCurrentOrder = functions.https.onRequest(async (req, res) => {
const useruid = req.query.uid;
const itemName = req.query.itemName;
const itemPrice = req.query.itemPrice;
const itemQuantity = req.query.itemQuantity;
console.log('This is in useruid: ', useruid);
const data = { [useruid] : {
'Item Name': itemName,
'Item Price': itemPrice,
'Item Quantity': itemQuantity,
}};
const writeResult = await admin.firestore().collection('Current Orders').add(data);
res.json({result: data});
});
This is the part that's giving me all sorts of errors:
exports.getTotal = functions.firestore.document('Current Orders/{documentId}').onCreate((snap, context) => {
const data = snap.data();
for(const i in data){
console.log('This is in i: ', i);
}
return snap.ref.set({'testing': 'testing'}, {merge: true});
});
Whenever I have this, the console will always give me:
functions: Error: 2 UNKNOWN:
at Object.callErrorFromStatus (/Users/user/firecast/functions/node_modules/#grpc/grpc-js/build/src/call.js:30:26)
at Object.onReceiveStatus (/Users/user/firecast/functions/node_modules/#grpc/grpc-js/build/src/client.js:175:52)
at Object.onReceiveStatus (/Users/user/firecast/functions/node_modules/#grpc/grpc-js/build/src/client-interceptors.js:341:141)
at Object.onReceiveStatus (/Users/user/firecast/functions/node_modules/#grpc/grpc-js/build/src/client-interceptors.js:304:181)
at Http2CallStream.outputStatus (/Users/user/firecast/functions/node_modules/#grpc/grpc-js/build/src/call-stream.js:116:74)
at Http2CallStream.maybeOutputStatus (/Users/user/firecast/functions/node_modules/#grpc/grpc-js/build/src/call-stream.js:155:22)
at Http2CallStream.endCall (/Users/user/firecast/functions/node_modules/#grpc/grpc-js/build/src/call-stream.js:141:18)
at Http2CallStream.handleTrailers (/Users/user/firecast/functions/node_modules/#grpc/grpc-js/build/src/call-stream.js:273:14)
at ClientHttp2Stream.<anonymous> (/Users/user/firecast/functions/node_modules/#grpc/grpc-js/build/src/call-stream.js:322:26)
at ClientHttp2Stream.emit (events.js:210:5)
Caused by: Error
at WriteBatch.commit (/Users/user/firecast/functions/node_modules/#google-cloud/firestore/build/src/write-batch.js:415:23)
at DocumentReference.create (/Users/user/firecast/functions/node_modules/#google-cloud/firestore/build/src/reference.js:283:14)
at CollectionReference.add (/Users/user/firecast/functions/node_modules/#google-cloud/firestore/build/src/reference.js:2011:28)
**at /Users/user/firecast/functions/index.js:43:76**
at /usr/local/lib/node_modules/firebase-tools/lib/emulator/functionsEmulatorRuntime.js:593:20
at /usr/local/lib/node_modules/firebase-tools/lib/emulator/functionsEmulatorRuntime.js:568:19
at Generator.next (<anonymous>)
at /usr/local/lib/node_modules/firebase-tools/lib/emulator/functionsEmulatorRuntime.js:8:71
at new Promise (<anonymous>)
at __awaiter (/usr/local/lib/node_modules/firebase-tools/lib/emulator/functionsEmulatorRuntime.js:4:12)
⚠ Your function was killed because it raised an unhandled error.
Even if I comment out the function that I think is giving me the error, I will still run into this problem (and when I run the sample function found on the official cloud function guide too!)
I know there is definitely something that I am doing horribly wrong on the background trigger (and would love to have someone be kind enough to show me how to write such function/get me startted)
What am I doing wrong here? Or is this some sort of the emulator bug?
I think I found it. Although I think there is better solution possible.
On completely new system+firebase I have used this firebase emulators tutorial to create first onCreate trigger called makeUppercase and it worked. Than I added your getTotal and it was not working and as well it spoiled the makeUppercase trigger as well!
I started to test some changes. Tried many times and, finally, I have removed "space" character from collection name like this:
exports.getTotal = functions.firestore.document('CurrentOrders/{documentId}')...etc.
Both triggers started working as well (used fresh VM with Windows+node12). It's possible that it will be working on real Firestore instance. So it seems the "space" in collection name is generating some errors in whole index.js.

firebase onSnapshot gets update before create is complete

I have a "post" that listens to changes on its comments in react like so:
// React hook state
const [comments, setComments] = useState([])
// My listener in useEffect
db.collection(`users/${userId}/posts/${postId}/comments`)
.onSnapshot((querySnapshot) => {
let newComments = []
querySnapshot.forEach(function (doc) {
newComments.push({
id: doc.id,
...doc.data()
})
})
setComments(newComments)
})
When the user creates a new comments, I set a loading state and disable the comment section
// React hook
const [isLoading, setLoading] = useState(false)
// Add comment
const addComment = () => {
const comment = {text:"hello"}
setSaving(true)
db.collection(`users/${postUid}/posts/${postId}/comments`).doc()
.set(comment)
.then(()=>{
setSaving(false)
})
}
My problem is (a good problem to have), the subscription onSnapshot gets the new comment before my addComment callback is completed, creating some visual issues:
- Makes the app look buggy when the comment input is still loading but the comment already there
- If there is an error (ex: database permission issue), the comment shows up in the list and then disappears...
Any idea what I can change to not have the onSnapshot update before the create is done?
As explained here in the doc:
Local writes in your app will invoke snapshot listeners immediately.
This is because of an important feature called "latency compensation."
When you perform a write, your listeners will be notified with the new
data before the data is sent to the backend.
Retrieved documents have a metadata.hasPendingWrites property that
indicates whether the document has local changes that haven't been
written to the backend yet.
See also the following remark in the "Listen to multiple documents in a collection" section:
As explained above under Events for local changes, you will receive
events immediately for your local writes. Your listener can use the
metadata.hasPendingWrites field on each document to determine whether
the document has local changes that have not yet been written to the
backend.
So you can use this property to display the change only if it has been written to the back-end, something along the following lines (untested):
db.collection(`users/${userId}/posts/${postId}/comments`)
.onSnapshot((querySnapshot) => {
let newComments = []
querySnapshot.forEach(function (doc) {
if (!doc.metadata.hasPendingWrites) {
newComments.push({
id: doc.id,
...doc.data()
})
}
})
setComments(newComments)
})

React native firebase database on value change not triggered

I have a react native app and using firebase database.
I try to use the on or once functions to get items from database but I don't know what I am doing wrong because I don't get any data.
This is my code to get data from firebase database:
firebase.database().ref("messages/").once('value', snapshot => {console.log("snapshot value", snapshot)});
I try the command from above also with on instead of once and same result. The console.log is never called.
When I am adding messages everything it's ok and the messages appear in the firebase console. For adding messages I am doing like this:
firebase.database().ref("messages/").push(message);
For firebase I am using this library: rnfirebase.io
This are the versions used:
React: 16.6.0-alpha.8af6728
React native: 0.57.4
React native firebase: 5.0.0
The Firebase once returns a promise so you have to use then after using value.
The code should be like
firebase.database().ref('tableNameHere').once('value').then(snapshot => {
if(snapshot.exists()){
console.log(snapshot.val());
}
}).catch(err => console.log(err));
when using on value the function will invoke on change in value like on CRUD operation
firebase.database().ref('tableNameHere').on('value', snapshot => {
if(snapshot.exists()){
console.log(snapshot.val());
}
},(err) => console.log(err))

Image upload with Firebase React Native

I want to upload an image to Firebase Storage from a React Native app, the Firebase web sdk only works on iOS so I am giving Firebase React Native a go. The docs are empty but someone pointed my to the old docs so my code looks like this.
firebase.storage().ref('/rn-firebase2.jpg').putFile(imgFile.uri)
.on('state_changed', snapshot => {
//Current upload state
console.log('state_changed: ', snapshot);
}, err => {
//Error unsubscribe();
console.log('err: ', err);
}, uploadedFile => {
//Success unsubscribe();
console.log('uploadedFile: ', uploadedFile);
});
When ran, I get
"Possible Unhandled Promise Rejection (id: 0):". A file is uploaded to
the Cloud Storage but it unusable.
Anyone has successfully gotten this to work on iOS and Android? Any help would be much appreciated, thanks!

Resources