I'm trying to implement a feature in my app. I am using an Android device (not emulator).
Let's say I don't have internet connection an I have an array saved in my Asyncstorage and each time I push a button I insert a new item on that array.
I am using react-native-netinfo to detect when the connection changes, so what I'm trying to do is:
When the NetInfo.addEventListener triggers and if the connection status is true, I want to send that array to my API, the event is triggering well, if I turn off the wifi and cellular data I get connection status false, everything is ok. But when I console.log my array and try to send it to my API is doesn't print the new items into Asyncstorage.
If I restart the app, that same console.log prints the correct information when the connection changes, but again, if I push new items and the connection changes again, it doesn't print the new items added to the Asyncstorage (I know they're there because if I go to another screen, they're there)
This is my code:
useEffect(() => {
const unsubscribe = NetInfo.addEventListener((state) => {
handleConnectionChange(state);
console.log("Connection type", state.type);
console.log("Is connected?", state.isConnected);
});
return () => {
unsubscribe();
};
}, []);
const handleConnectionChange = (state) => {
console.log("Array: ", tickets);
//tickets should be updated with the new tickets but is not, until I refresh the app.
//tickets rendered ok and are printed ok on any other console.log outside of this event.
if (state.isConnected && tickets.length > 0) {
console.log("TRY TO SYNC");
callAPI()
}
setConnectionStatus(state.isConnected);
};
I appreciate any help. Thanks in advance.
Related
I'm using the firebase_messaging package on my flutter app and it works perfectly for everything except that when the app on the background and I get a notification it only opens the app and never do what I ask it does after opening the app ..here is my code:
Future<void> _firebaseMessagingBackgroundHandler(RemoteMessage message) async {
// If you're going to use other Firebase services in the background, such as Firestore,
// make sure you call `initializeApp` before using other Firebase services.
await Firebase.initializeApp();
print("Handling a background message: ${message.messageId}");
final dynamic data = message.data;
print("data is $data");
if(data.containsKey('request_id')) {
print("we are inside ..!");
RegExp exp = RegExp(r'\d+');
var id = int.parse(exp.firstMatch(data['request_id']!)!.group(0)!);
OpenRequestsController openRequestsController = Get.isRegistered<OpenRequestsController>()?Get.find():Get.put(OpenRequestsController());
OpenRequest matchingRequest = openRequestsController.openRequestsList.firstWhere((request) => request.id == id);
print("the request from the list is $matchingRequest");
openRequestsController.openRequestDetails(matchingRequest,false);
}
}
what happens here is that it tries to run the whole function when the message is received not when clicked .. and ofc it fails because the app is not already running in the foreground
For opening the application and moving to the said screen you need to implement onMessageOpenedApp in the initstate of your first stateful widget which will let the application to know that it is supposed to open the application when a notification being clicked. The code function should look like this:
FirebaseMessaging.onMessageOpenedApp.listen((message) {
Get.to(() => const MainScreen()); // add logic here
});
It is better if you could assign identifiers for the type of screens you want to open on clicking a particular notification while sending the notification and implement an if-else or switch statement here on the basis of message type.
Thanks
I am currently working on a simple app for scanning, reading data from an NFC card (in my case a Mifare NFC card) and displaying in on the screen. I have built it using this example.
The app should work both on Android and iOS, but for the moment, I have tested it only on an android device (an Oppo device with NFC capablities and developer mode activated).
At the launch of the app, everything seems to be working fine, the NfcManager has been successfully started, but there is an issue when the app tries to request the technology for reading the card, namely, I have to bring the app first in the background and then again in the foreground so that the message requestTechnology success is displayed, otherwise, it's simply not called.
After this, the promise NfcManager.getTag() gets rejected with the error message: no reference available.
Here is my code:
componentDidMount() {
NfcManager.start({
onSessionClosedIOS: () => {
alert('ios session closed');
},
}).then(() => console.warn('NfcManager started')) // successfully started
.catch((error) => alert('Error starting NfcManager: ', error));
}
{... componentWillUnmount and render method ...}
_read = async () => {
try {
let tech = Platform.OS === 'ios'
? NfcTech.MifareIOS : [NfcTech.MifareClassic, NfcTech.NfcA, NfcTech.IsoDep, NfcTech.Ndef];
let resp = await NfcManager.requestTechnology(tech, {
alertMessage: 'Ready to do some custom Mifare cmd!'
})
.then((value) => alert('requestTechnology success', value)) // here the value is empty, so no NfcTech
.catch(() => console.warn('reuqestTechnology error'));
const tag = await NfcManager.getTag()
.then((value) => alert('Tag event: ', value))
.catch((err) => console.warn('error getting tag: ', err));
// this part of the code is reached, but not working properly since the tag.id is not correctly retrieved
if (Platform.OS === 'ios') {
resp = await NfcManager.sendMifareCommandIOS([0x30, 0x00]);
} else {
resp = await NfcManager.transceive([0x30, 0x00]);
}
console.warn('Response: ', resp);
this._cleanUp();
} catch (ex) {
console.warn(ex);
this._cleanUp();
}
}
If I scan the card against the device, it makes the sound like it has been scanned, but nothing seems to be displayed.
Does anyone know why does the app needs to be brought to the background so that the technology is requested? And second, does the fail of the getTag() method have anything to do with it?
I hope anyone can help me with this issue, I have been struggling with this problem for quite some time and I haven't found any solution.
May be related to github.com/revtel/react-native-nfc-manager/issues/423 ?? there seems to be a scenario where this package does not correctly configure enableForegroundDispatch and manually pausing and resuming the App by sending it to the background would fix it.
I am working on one app in react-native. I want to do this kind of functionality.
1)When the user will log in from 1st device with their credential at that time I am storing device ID in my firestore database.
now, If the user will do sign in from 2nd device with the same credential at that time I am going to log out that user from 1st device. I have implemented that logic.
But the issue is this is not happening in real-time. When I will restart the 1st device's application at that time this logic works.
Is there any type of method that triggers when my database updates?
I want this logic to works immediately when the user logs in from another device with the same ID.
const onAuthStateChanged = async (user) => {
setUser(user);
if (user) {
//here i am checking for token
await firestore()
.collection('Users')
.doc(user.email)
.get()
.then((documentSnapshot) => {
const data_device = documentSnapshot.data();
if (device_id != data_device.device_token) {
alert('you are signned in other device'); //and if not as same then logout
logout();
}
});
}
if (inisiallizing) setInisiallizing(false);
};
The onAuthStateChanged only run when the authState changed (Login, logout, register) and its state is run on it own (not run in multiple environment, devices).
As your usecase, I think you should listen to a documents on Firestore that store your deviceId
firestore()
.collection('Users')
.doc(user.email)
.onSnapshot((doc) => {
// Your logic to logout here
})
The above code will run everytime document firestore().collection('Users').doc(user.email) has update
I ran into a problem with my flutter app where when it's minimized or the phone is put to sleep for too long (~5+ minutes), the app stops listening to firestore changes. One solution that I came across was to send push notifications to reawaken the device. While it seems to have fixed minimizing problem (the app now responds to changes), however it still suffers from the sleep problem. I noticed that the app still receives the push notifications, but the screen doesn't light up upon receiving them. Could that be why? Is there something that I can do to force the app to connect to the internet? I'm trying to think of a solution like sending a data payload to change the data locally, but I'm not sure if that's the optimal approach (or if it would even work). I'll post my firebase cloud function for sending messages on a doc update:
exports.sendLobbyNotificationTest = functions.firestore
.document("Lobbies/{lobbyCode}")
.onUpdate((change) => {
console.log("Checking for need of push notification...");
// const oldValue = change.before.data() || {};
const newValue = change.after.data() || {};
if (newValue.pushNotification == true) {
console.log("Found a push notification request for: ",
newValue.lobbyCode, "!");
// Set lobby back to false
admin.firestore().collection("Lobbies")
.doc(newValue.lobbyCode).update({
pushNotification: false,
});
return admin.messaging().sendToTopic(newValue.lobbyCode, message)
.then((result) => {
console.log("Message sent successfully: ", result);
// usersRef.where("lobbyCode", "==", newValue.lobbyCode).get()
// .then(function(querySnapshot) {
// querySnapshot.forEach(function(doc){
// })
// })
}).catch((err) => {
console.error("Error sending message: ", err);
});
}
console.log("No message needs to be sent!");
// return dummy value to prevent error
return 0;
});
const message = {
notification: {
title: "Bzzzt!",
body: "You've been buzzed!",
},
};
Is there something I'm missing?
Update: I think it just doesn't work because the phone is locked, once unlocked it begins to function normally.
I think figured out why from reading here: https://developer.android.com/training/monitoring-device-state/doze-standby.html (I had trouble finding this).
Basically if I use the right priority settings for android and ios (priority & content_available) it will bring the app out of idle and listen for changes.
The Ionic documentation for call-number is scant.
I'm trying to figure out how I can detect when a call has been disconnected. I want my app to fire a message and update a database (with call duration and other metadata) upon call completion.
Does anyone know how to do this?
Well there are two ways a phone call could end and that is handled by the onSuccess and onError parameters of the callNumber function, you can provide the handling of the call end database log via these functions.
ie.
this.callNumber.callNumber(
successres => {
// handle the success result
console.log(successres);
},
err => {
// handle errors while calling
console.log(err);
},
"18001010101",
true);