How to Read and Write Data from Firebase Database? - firebase

I have many problems to read data from a simple Firebase DB and to store it.
It's the first time that I use it so any help will be appreciated.
The solution is Xamarin.Forms and this is the Android part, my main problem.
This is my DB Structure:
I need to read and write the "number" value stored.
I add all Firebase package like Firebase.Database and Firebase.Connection
In my Android Prj I have a class with these:
MainActivity.cs
private void InitFirebaseAuth()
{
var options = new FirebaseOptions.Builder()
.SetApplicationId("******")
.SetApiKey("*******")
.SetDatabaseUrl("******")
.Build();
if (app == null)
app = FirebaseApp.InitializeApp(this, options, "SaloneB");
}
FirebaseHelper.cs
DatabaseReference databaseReference;
FirebaseDatabase database
public void Connect()
{
database = FirebaseDatabase.GetInstance(MainActivity.app);
}
First I call Connect then I try something like this without result:
FirebaseClient firebase = new FirebaseClient("*****");
//This to retrieve value
var items = await firebase
.Child("number_of_user") //name of the table
.OnceAsync(); //retrieve the value
Items result is 0 elements
Thanks for help

Related

How can I retrieve only the latest data entry from firebase realtime database that frequently updates entries

I am trying to create an Android app that can monitor sensor reading in real-time. This is the code I used for retrieving the data:
class _ReadPageState extends State<ReadPage>{
String _displayText = 'results go here';
final _database = FirebaseDatabase.instance.ref();
FirebaseDatabase database = FirebaseDatabase.instance;
#override
void initState(){
super.initState();
_activateListeners();
}
void _activateListeners(){
_database.child("temperature").onValue.listen((event){
final temperature = event.snapshot.value;
setState(() {
_displayText = 'temperature= $temperature';
});
});
}
When I run the app, it posts all of the data written in the realtime database like this
enter image description here
Since you said that you want to get only the last updated record, then the simplest solution that you have is to sort the results of your query according to a timestamp field descending and call .limit(1). The sorting can be done on the client, or using the solution from my following answer:
Sort data to RecyclerView based on latest date from Firebase

Retrieving, comparing and sending data from realtime database firebase to flutter

what I'm trying to do is fetch data from realtime database in table picture_has_changed, and when pressed that it changes from 0 to 1 and 1 to 0.
This is what I have done so far, but when I try to convert the value it says that it isn't a integer value. So any help would be great.
The code:
openGatePhoto() async {
await Firebase.initializeApp();
FirebaseStorage storage = FirebaseStorage.instance;
var storageReference =
storage.ref().child("picture_has_changed");
if (storageReference == 0) {
storageReference = "1";
} else {
storageReference = "0";
}
I tried using set function also, but it didn't work here it is:
storageReference.child("picture_has_changed").set(val);
Thanks in advance :)
You're trying to access the Realtime Database through the Storage API. While both products are part of Firebase, their APIs are completely separate and you can't use the API for one to access the other.
To access the value from the Realtime Database, do something like this:
var reference =
FirebaseDatabase.instance.ref().child("picture_has_changed");
var snapshot = await reference.once();
print(snapshot.value)
I'd also recommend checking out the usage instructions for this part of the library.

Flutter: How to move a firebase node - API REST vs SDK

I have a node in Firebase that has multiple childs and childs of childs. I want to move all from one place to another, then I made a function with Firebase REST API, but I would like to optimize it and migrate it to SDK.
The function I'm using with API REST is:
Future<bool> moverLoteActual() async {
//TO READ FROM SOURCE PATH
final urlLoteActual = '$_PATH_ORIGEN.../loteActual.json?auth=${_prefs.token}';
final resp = await http.get(urlLoteActual);
//TODO: Probably I neew an error management here
//TO COPY IN DESTINATION
final urlLotesCerrados = '$PATH_DESTINO.../lotesCerrados.json?auth=${_prefs.token}';
final resp2 = await http.post(urlLotesCerrados, body: resp.body);
final decodedData2 = json.decode(resp2.body);
print(decodedData2);
//TO DELETE THE SOURCE NODE
final resp3 = await http.delete(urlLoteActual);
print(json.decode(resp3.body));
return true;
}
I tried with SDK but I get a lot of parsing errors and finally I think a sequential approach as I implemented with API REST is not the best way.
How can I get this change of location using SDK?
I found a solution.
First, you need to understand that snapshot.value is a Map<dynamic, dynamic>, then you need to assign the answer (resp) to this type of map.
Later, you need to copy the node in a new location, then you need to convert the previous Map to a new one of other type (Map<String, dynamic> to write)
The last step (delete the original node) is easy... the standard function.
Future<bool> moverLoteActual() async {
//TO READ FROM SOURCE PATH
Map<dynamic, dynamic> _map = new Map<dynamic, dynamic>();
Query resp = db.child('$_PATH_ORIGEN.../loteActual');
final snapshot = await resp.once();
_map = snapshot.value;
//TO COPY IN DESTINATION
db.child('$PATH_DESTINO.../lotesCerrados')
.push().update(Map<String, dynamic>.from(_map));
//TO DELETE THE SOURCE NODE
db.child('$_PATH_ORIGEN.../loteActual').remove();
return true;
}
PD. db is the Firebase Database Reference

How to properly sync Xamarin iOS Sqlite using Azure Mobile Services

In my Xamarin iOS PCL app I'm trying to insert a record into my local Sqlite table, have it synced via Azure Mobile Services, and then read it back.
Here is the code:
private IMobileServiceSyncTable<Job> jobTable;
public async Task InitializeAsync()
{
var store = new MobileServiceSQLiteStore("localdata.db");
store.DefineTable<Job> ();
await this.MobileService.SyncContext.InitializeAsync(store);
jobTable = this.MobileService.GetSyncTable<Job>();
jobTable = this.MobileService.GetSyncTable<Job>();
JObject newJob = new JObject ();
newJob.Add ("Id","job_123");
jobTable.InsertAsync (newJob);
this.MobileService.SyncContext.PushAsync();
var readResult = jobTable.ReadAsync ().Result.AsQueryable();
var resultList = from data in readResult
select data;
var resultCount = resultList.Count ();
}
So far - nothing gets synced up with my Sql Server db (which is on the recieving end of the Mobile Services), and the resultCount remain at 0
I'm sure I do something wrong here, just can't seem to nail what exactly.
-Eugene
You should use PullAsync instead of ReadAsync. Also, you need to await the call to all of your async method calls, such as InsertAsync, PushAsync, and PullAsync.
See this tutorial for a detailed example: http://azure.microsoft.com/en-us/documentation/articles/mobile-services-xamarin-ios-get-started-offline-data/

Get users by name property using Firebase

I'm trying to create an application where I can get/set data in specific users accounts and I was tempted by Firebase.
The problem I'm having is that I don't know how to target specific users data when my structure looks like this:
online-b-cards
- users
- InnROTBVv6FznK81k3m
- email: "hello#hello"
- main: "Hello world this is a text"
- name: "Alex"
- phone: 12912912
I've looked around and I can't really find anything on how to access individual data let alone when they're given some random hash as their ID.
How would I go about grabbing individual user information based of their name? If there is a better way of doing this please tell me!
Previously, Firebase required you to generate your own indexes or download all data at a location to find and retrieve elements that matched some child attribute (for example, all users with name === "Alex").
In October 2014, Firebase rolled out new querying functionality via the orderByChild() method, that enables you to do this type of query quickly and efficiently. See the updated answer below.
When writing data to Firebase, you have a few different options which will reflect different use cases. At a high level, Firebase is a tree-structured NoSQL data store, and provides a few simple primitives for managing lists of data:
Write to Firebase with a unique, known key:
ref.child('users').child('123').set({ "first_name": "rob", "age": 28 })
Append to lists with an auto-generated key that will automatically sort by time written:
ref.child('users').push({ "first_name": "rob", "age": 28 })
Listen for changes in data by its unique, known path:
ref.child('users').child('123').on('value', function(snapshot) { ... })
Filter or order data in a list by key or attribute value:
// Get the last 10 users, ordered by key
ref.child('users').orderByKey().limitToLast(10).on('child_added', ...)
// Get all users whose age is >= 25
ref.child('users').orderByChild('age').startAt(25).on('child_added', ...)
With the addition of orderByChild(), you no longer need to create your own index for queries on child attributes! For example, to retrieve all users with the name "Alex":
ref.child('users').orderByChild('name').equalTo('Alex').on('child_added', ...)
Engineer at Firebase here. When writing data into Firebase, you have a few different options which will reflect different application use cases. Since Firebase is a NoSQL data store, you will need to either store your data objects with unique keys so that you can directly access that item or load all data at a particular location and loop through each item to find the node you're looking for. See Writing Data and Managing Lists for more information.
When you write data in Firebase, you can either set data using a unique, defined path (i.e. a/b/c), or push data into a list, which will generate a unique id (i.e. a/b/<unique-id>) and allow you to sort and query the items in that list by time. The unique id that you're seeing above is generated by calling push to append an item to the list at online-b-cards/users.
Rather than using push here, I would recommend using set, and storing the data for each user using a unique key, such as the user's email address. Then you can access the user's data directly by navigating to online-b-cards/users/<email> via the Firebase JS SDK. For example:
function escapeEmailAddress(email) {
if (!email) return false
// Replace '.' (not allowed in a Firebase key) with ',' (not allowed in an email address)
email = email.toLowerCase();
email = email.replace(/\./g, ',');
return email;
}
var usersRef = new Firebase('https://online-b-cards.firebaseio.com/users');
var myUser = usersRef.child(escapeEmailAddress('hello#hello.com'))
myUser.set({ email: 'hello#hello.com', name: 'Alex', phone: 12912912 });
Note that since Firebase does not permit certain characters in references (see Creating References), we remove the . and replace it with a , in the code above.
You can grab the details by the following code.
FirebaseDatabase database = FirebaseDatabase.getInstance();
DatabaseReference myRef = database.getReference("users");
myRef.orderByChild("name").equalTo("Alex").addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot childDataSnapshot : dataSnapshot.getChildren()) {
Log.d(TAG, "PARENT: "+ childDataSnapshot.getKey());
Log.d(TAG,""+ childDataSnapshot.child("name").getValue());
}
I think the best approach is to define the ids of the users based o the auth object provided by the Firebase. When I create my users, I do:
FirebaseRef.child('users').child(id).set(userData);
This id comes from:
var ref = new Firebase(FIREBASE);
var auth = $firebaseAuth(ref);
auth.$authWithOAuthPopup("facebook", {scope: permissions}).then(function(authData) {
var userData = {}; //something that also comes from authData
Auth.register(authData.uid, userData);
}, function(error) {
alert(error);
});
The Firebase auth services will always ensure a unique id among all their providers to be set at uid. This way always you will have the auth.uid and can easily access the desired user to update it, like:
FirebaseRef.child('users').child(id).child('name').set('Jon Snow');
This was a paraphrasing of a post that helped me when trying to access the auto-generated unique id. Access Firebase unique ids within ng-repeat using angularFire implicit sync
Thanks, bennlich (source):
Firebase behaves like a normal javascript object. Perhaps the example below can get you on the right track.
<div ng-repeat="(name, user) in users">
{{user.main}}
</div>
Edit: Not 100% sure of your desired outcome, but here's a bit more that might spark an 'aha' moment. Click on the key that you are trying to access right in your Firebase dashboard. From there you can use something like:
var ref = new Firebase("https://online-b-cards.firebaseio.com/users/<userId>/name);
ref.once('value', function(snapshot) {
$scope.variable= snapshot.val();
});
This is how to access the auto generated unique keys in Firebase:
data structure:
- OnlineBcards
- UniqueKey
database.ref().on("value", function(snapshot) {
// storing the snapshot.val() in a variable for convenience
var sv = snapshot.val();
console.log("sv " + sv); //returns [obj obj]
// Getting an array of each key in the snapshot object
var svArr = Object.keys(sv);
console.log("svArr " + svArr); // [key1, key2, ..., keyn]
// Console.log name of first key
console.log(svArr[0].name);
}, function(errorObject) {
console.log("Errors handled: " + errorObject.code);
});
The simplest way is to stop using the .push(){}
function which will generate that random key. But instead use the .update(){} function where you may specify the name of the child instead of having the random key.
Retrieving data:
In your database, you are using a random id that is generated using the push(), therefore if you want to retrieve the data then do the following:
Using Firebase in Android App:
DatabaseReference ref=FirebaseDatabase.getInstance().getReference().child("users");
ref.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot datas : dataSnapshot.getChildren()) {
String name=datas.child("name").getValue().toString();
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
Using Firebase in Javascript:
firebase.database().ref().child("users").on('value', function (snapshot) {
snapshot.forEach(function(childSnapshot) {
var name=childSnapshot.val().name;
});
});
Here you have the snapshot(location of the data) at users then you loop inside all the random ids and retrieve the names.
Retrieving data for a Specific User:
Now if you want to retrieve information for a specific user only, then you need to add a query:
Using Firebase in Android App:
DatabaseReference ref=FirebaseDatabase.getInstance().getReference().child("users");
Query queries=ref.orderByChild("name").equalTo("Alex");
queries.addListenerForSingleValueEvent(new ValueEventListener() {...}
Using Firebase with Javascript
firebase.database().ref().child("users").orderByChild("name").equalTo("Alex").on('value', function (snapshot) {
snapshot.forEach(function(childSnapshot) {
var name=childSnapshot.val().name;
});
});
Using orderByChild("name").equalTo("Alex") is like saying where name="Alex" so it will retrieve the data related to Alex.
Best Way:
The best thing is to use Firebase Authentication, thus generating a unique id for each user and using it instead of a random id push(), this way you do not have to loop through all the users since you have the id and can easily access it.
First, the user needs to be signed in then you can retrieve the unique id and attach a listener to retrieve the other data of that user:
Using Firebase with Android:
DatabaseReference ref = FirebaseDatabase.getInstance().getReference("users");
String uid = FirebaseAuthentication.getInstance().getCurrentUser().getUid();
ref.child(uid).addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
String name=dataSnapshot.child("name").getValue().toString();
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
Using Firebase with Javascript:
var user = firebase.auth().currentUser;
var uid=user.uid;
firebase.database().ref().child("users").child(uid).on('value', function (snapshot) {
var name=snapshot.val().name;
});
The simplest and better way to add unique Id to ur database according to authenticated user is this:
private FirebaseAuth auth;
String UId=auth.getCurrentUser().getUid();
FirebaseDatabase database = FirebaseDatabase.getInstance();
DatabaseReference myRef = database.getReference("Users");
User user = new User(name,email,phone,address,dob,bloodgroup);
myRef.child(UId).setValue(user);
The UId will be a unique Id for a specific authenticated email/user

Resources