How to retrieve data from firebase using the key value - javascript

I am working on a web application and I purely used javascript to store read and delete data. So it's a blog-type application in which I currently am working on, and my database schema is like the following picture.
Now the problem is I want to retrieve values of posts (like description, imageurl, task) by key value postCategory which is "software engineering".

You need to use the equalTo
postsRef.orderByChild("postCategory").equalTo("software engineering").addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(DataSnapshot dataSnapshot, String prevChildKey) {
System.out.println(dataSnapshot.getKey());
}
// ...
});

Related

Restart Id=1 when deleting every record in a table? (Angular + Spring Boot + MySQL)

I'm developing a simple CRUD application using Angular for the Frontend part, Spring Boot for the Backend and MySQL for the Database.
I've managed to insert, retrieve and Update/Delete the values inside my table, but I'm struggling with restarting the value of the Id (which I set as Primary Key) when I delete all the records from my CRUD table. I mean, if I have 10 records (Id = 1,...,10) and I delete all of them, the next first insert will have Id=1 and I would like it to be equal to 1. I'm using InnoDB as the engine.
Frontend part -
.html file
<button class="m-3 btn btn-sm btn-danger" (click)="removeAllRecords()">
Remove All
</button>
.ts file
removeAllRecords(): void {
if(confirm("Are you sure you want to delete ALL your records?")){
this.recordService.deleteAll()
.subscribe(
response => {
console.log(response);
this.refreshList();
},
error => {
console.log(error);
});
}
}
service.ts file
const baseUrl = 'http://localhost:8080/api/records';
deleteAll(): Observable<any> {
return this.http.delete(baseUrl);
}
Backend part - I'm using on Spring Boot the Datajpa repository:
model file
#Entity
#Table(name = "crud")
public class Record{
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
....
}
controller file
#DeleteMapping("/records")
public ResponseEntity<HttpStatus> deleteAllRecords() {
try {
contactRepository.deleteAll();
return new ResponseEntity<>(HttpStatus.NO_CONTENT);
} catch (Exception e) {
return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
}
}
Now, I think something must be done in the above function or something on the definition of the table, but I'm not understand what and how...can you please help me?
P.S. I'm using using these settings in the application.properties file:
spring.datasource.url= jdbc:mysql://localhost:3306/codejavadb?useSSL=false
spring.datasource.username= root
spring.datasource.password= *pwd*
spring.jpa.show-sql=true
spring.jpa.properties.hibernate.dialect= org.hibernate.dialect.MySQL5InnoDBDialect
spring.jpa.hibernate.ddl-auto= update
hope I made myself clear, I'm quite new with all these kinds of tools and syntaxes, any help would be really appreciated, thanks! :)
You can directly add a logic to set primary key. before making any insert, check the counts of records. If there are records, next primary key will be +1. If there is no record, it will return 0 so +1 will assign primary key as 1 to that insertion.

Change Geofire firebase structure with ionic [duplicate]

I am storing location data via GeoFire in my database, here is the structure:
geofire
-Ke1uhoT3gpHR_VsehIv
-Kdrel2Z_xWI280XNfGg
-g: "dr5regw90s"
-l
-0: 40.7127837
-1: -74.00594130000002
It is avised to store a location's information and geofire data in separate nodes, however I see an advantage to storing some extra data under these geofire nodes, such as the name of a business. This way I'd only have to make only one call to my Firebase to fetch nearby locations as well as their names.
Is this achievable via the key_entered method? Has anyone created a similar solution? Is this truly that bad of an idea even if the location info is consistently updated?
Any input is appreciated!
Firstly the structure you are using for the app is wrong.
let us take an example of users app
When you use Geofire, you have two lists of data:
a list of user details for each user
a list of latitude and longitude coordinates for each user
You are trying to store both in same structure like this
"users" : {
<userId> : {
"userData" : "userData",
<geofireData>
...
}
}
Trying to store userdata and geofiredata in one node is a bad idea, since you're mixing mostly static data (the properties of your user) with highly volatile data (the geo-location information).Separating the two out leads to better performance, which is why Geofire enforces it.
This is why when you try to add geolocation data to a user node it overwrites previous user details for that node.
Your database structure should be like this.
"Users" : {
<UserId> : {
"UserData" : "UserData",
...
}
}
"Users_location" : {
<UserId> : {
<geofireData> ...
}
}
Hence for the same user Id you create 2 structures one for user details and another for geolocation details of that user.
How to push the user and set the geofire data.
String userId = ref.child("users").push().getKey();
ref.child("users").child(userId).setValue(user);
geoFire = new GeoFire(ref.child("user_location"));
geoFire.setLocation(userId, new GeoLocation(lattitude, longitude));
the userId you use in geolocation is same as the one you got during push().
Hence for each userId you have userdetails in one structure and location details in anotehr structure.
To get the data, first you need to do GeoQuery at users_location node and then get the data on the onKeyEntered method. The parameter key is userId from my example.
geoFire=newGeoFire(FirebaseDatabase.getInstance().getReference().child("users_location");
geoQuery = geoFire.queryAtLocation(geoLocation), radius);
geoQuery.addGeoQueryEventListener(new GeoQueryEventListener() {
#Override
public void onKeyEntered(String key, GeoLocation location) {
//retrieve data
//use this key which is userId to fetch user details from user details structure
}
};
Happy coding :)
It might be late but just in case someone else is facing the same issue.
It's very possible to integrate and manipulate GeoFire data with existing data.
The main challenge faced by many developers is the fact that they can't update the GeoFire geolocation without deleting the existing data using geoFire.setLocation("id", location); as reported in this issue geofire-java/issues/134.
This is my solution for that.
1. Setting mixed data with GeoFire on FireBase
Let's consider below Structure:
|-userExtra :
|-userId1 :
|- userId : "userId1",
|- userName : "Name1",
|- <geofireData> (i and g)
|...
|-userId2 :
|- userId : "userId2",
|- userName : "Name2",
|- <geofireData> (i and g)
|...
You can generate the geoHash with GeoHash geoHash = new GeoHash(location) and set the value to the child directly in the firebase.
/*Java Code*/
void setGeoFireMixData(UserExtra user, Location location){
DatabaseReference ref = FirebaseDatabase.getInstance().getReference();
ref = ref.child("users").child(user.userId);
//Setting userData if needed
ref.child("userId").setValue(user.id);
ref.child("Name").setValue(user.name);
// .... other references
//Setting GeoFire Data
GeoHash geoHash = new GeoHash(location);
ref.child("l").setValue(Arrays.asList(location.latitude, location.longitude));
ref.child("g").setValue(geoHash.getGeoHashString());
}
2. Fetching mixed data with GeoFire
About the question:
Is this achievable via the key_entered method? Has anyone created a similar solution? Is this truly that bad of an idea even if the location info is consistently updated?
I'd say, you can't retrieve both extra data and GeoFire using only the GeoQueryEventListener with onKeyEntered. You will need to use GeoQueryDataEventListener. For that, you can define the PoJo of your data considering the structure defined above.
...
GeoQueryDataEventListener geoQueryDataEventListener = new GeoQueryDataEventListener() {
#Override
public void onDataEntered(DataSnapshot dataSnapshot, GeoLocation location) {
UserExtra user = dataSnapshot.getValue(UserExtra.class);
actionOnUser(user);
}
...
};
...
geoQuery = geoFire.queryAtLocation(new GeoLocation(latitude,longitude), 0.5);
geoQuery.addGeoQueryDataEventListener(geoQueryDataEventListener);
...
The class UserExtra can be defined as below:
public class UserExtra implements Serializable {
String userId;
String name;
...
List<Double> l; //GeoLocation
String g;
}
That will give you all the data in your node including the geoFire data.
I had this solution I am using now for Javascript:
Save any extra info with key separated by symbol i.e. underscore
Make sure auth id is in the key, which is used in security rules to ensure only the user can write to their node
"rules": {
"geofire": {
".read":"true",
"$extrainformation_authid":{
".write":"$extrainformation_authid.contains(auth.uid)"
}
}
}
Client-side, separate the information by the underscore

Retrieve array from firebase database with start and end index and single where clause

I have Firebase Database structure like this:
i want to get records from index 2 to 5 where language is English.
FirebaseDatabase.getInstance()
.getReference("data").orderByChild("language").startAt("English").endAt("English");
its giving all record instead of language English.
what query should be done to retrieve data with single where clause and start and end index or length of response array?
It is not possible. Firebase queries can only have a condition on a single property or the key.
I have found solution to this problem by altering the structure of data to
Then query on different language differently.
FirebaseDatabase.getInstance()
.getReference().child("English").orderByKey().startAt("4").limitToFirst(2);
FirebaseDatabase.getInstance()
.getReference().child("Hindi").orderByKey().startAt("2").limitToFirst(3);
It's still possible using if condition :
DatabaseReference ref = FirebaseDatabase.getInstance()
.getReference("data").orderByKey().startAt(2).endAt(5);
ref.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot childSnapshot : dataSnapshot.getChildren()) {
Quote quote = childSnapshot.getValue(Quote.class);
if(quote.getLanguage().equals("English")){
//put your code here
}
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});

Assign new values in a Breeze entity

I'm developing a spa web application with BreezeJS and the DurandalJS Framework. I came accross a problem which I can't fix.
I have a entity called: Car, this entity contains name, number, owner, type en manufacturer. In this entity the name and number are filled in as the entity is created AND saved in the database. The other properties are allowed to be NULL.
This because the other values are filled in during a modal/ dialog screen. Here a user can select a owner from a list and also a type and manufacturer from a list. When the user selects one from a dropdown the selected value should be assigned to the value of the Car entity. How can I get this to work?
Car().Owner = newOwner;
Car.Owner() = newOwner;
This won't work. I tried a lot of combinations. Remember that the value was null first and that I can't insert a new value;S
Edit 1
Here the Entity Framework model of Car
using System;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace Estimate_App.Models
{
public class tblCar
{
[Key]
public int CarID { get; set; }
public string CarNumber { get; set; }
private DateTime _CreationDate;
public DateTime CreationDate
{
get { return this._CreationDate; }
set { this._CreationDate = DateTime.Now; }
}
//This is the Owner
[ForeignKey("Owner")]
public int? OwnerID { get; set; }
public tblOwner Owner { get; set; }
}
}
Here is what I put in my Car().Owner(), consider Container should be Car (this is an other project with the same problem)
I hover my mouse over newValue.
Edit 2
By a answer of Julián Yuste I also tried this but it didn't work. Here is the error:
When I do Container().Owner(newValue);
Edit 3
The code that fetches the owners
breeze.EntityQuery.from("Customers")
.using(dataservice.manager)
.execute().then(function (data) {
data.results.forEach(function (item) {
tempCustomerList.push(item); //ko.observableArray([]);
});
}).fail(function (data) {
});
Are you using the EntityManager from your dataservice object in order to create the newOwner object?
In other words, you probably shouldn't be doing this*:
var newOwner = new Owner();
newOwner.OwnerID = 123;
You should do this:
var newOwner = dataservice.manager.createEntity('Owner', { OwnerID: 123 });
*Note that can actually use new Owner(), but that requires you to define entity constructors in your code. :-)
For more information, check out the Breeze documentation: http://www.breezejs.com/documentation/creating-entities
Also, note that you can read the Breeze JavaScript code to help you understand the issue. If you search breeze.debug.js for your error message (An Entity cannot be attached to an entity in another EntityManager. One of the two entities must be detached first.), you will find the line of code that is causing the exception. It may be helpful to backtrack from there.
Edit
The answer to the question was to make sure that the EntityManager object is a Singleton (in this case, the dataservices.manager object).
In other words, use the same EntityManager object to update objects as you use to query for objects.
I think we need more information. Is the 'Owner' property an instance of another entity or is it a primitive type, i.e. string, number etc?
If it is an entity then I would first check that your 'newOwner' variable was also in fact an entity.
If owner is an observable, you need to asign the new value as: owner(newOwner).
Greetings.

Model DataAnnotation for asp.net mvc

Is there any way to get dataanotations for my models directly from my database?
I have a database with lot's of data and tables, so i am generating my model with entity framework from database, so i get classes, but i want to know can entity framework or some other orm get properities and constrains directly from database and put them in classes as data anotation like [required] or [datatype(datatype.emailadress)]
Yes. You can inherit the ModelMetadataProvider class:
public class LocalizedModelMetadataProvider : DataAnnotationsModelMetadataProvider
{
protected override ModelMetadata CreateMetadata(IEnumerable<Attribute> attributes, Type containerType,
Func<object> modelAccessor, Type modelType, string propertyName)
{
var metadata = base.CreateMetadata(attributes, containerType, modelAccessor, modelType, propertyName);
if (containerType == null || propertyName == null)
return metadata;
// Load all metadata from your database here.
return metadata;
}
}
I'm creating a project called Griffin.MvcContrib which is almost done and has a administration area where you can handle all localization (zero-code) for both models and validation messages.
By using it you can just implement the following interface to get support for your database:
// the actual code file has detailed explanations of each method.
public interface ILocalizedStringProvider
{
string GetModelString(Type model, string propertyName);
string GetModelString(Type model, string propertyName, string metadataName);
string GetValidationString(Type attributeType);
string GetEnumString(Type enumType, string name);
}
Update
Where is not important. And you do not have to use DataAnnotation attributes on your models (the [Display] attribute). I just inherit the DataAnnotationsModelMetadataProvider to be able to use the attributes.
Create the class anywhere.
Read from the database
Configure MVC to use it in global.asax
Example:
ModelMetadataProviders.Current = new YourModelMetadataProvider();

Categories

Resources