Firebase Auth State Persistence vanilla JS - javascript

I'm not sure I'm even attempting the right thing. Heres my issue.
I'm loading data to a screen if the user is authenticated. Its a summary screen. I can click a item and it will send me to a new "details" page (window.location) . I'm passing the ID in the URL and then doing a GET request to get the details to display. When I implement my rules on the firebase DB, (".read": "auth != null"), I get a "401 Unauthorized" error in the console.
So somehow I need to either pass the user to the details.js or set Persistence somehow. Anyone have any suggestions?
THIS IS THE CODE FROM THE MAIN.JS
auth.onAuthStateChanged(user => {
console.log(user);
if (user) {
database.on('value', function(data) {
myData = data.val()
keys = Object.keys(myData)
buildProperties();
})
// tempBuild()
} else {
$('.eachProperty').empty()
$('.eachProperty').append($(`<h1>You must be signed in to view properties</h1>`))
}
})
$('body').on('click', '.singleProp', function() {
id = $(this).attr('id')
window.location = "/details.html?id=" + id
})
THIS IS THE CODE FROM THE DETAILS.JS
var myLocation = location.search.slice(4)
$.get(`https://XXXXXX.firebaseio.com/property/${myLocation}/.json`).then(myProperty)
function myProperty(prop) {
$('.propAddress').text(prop.address)
$('.zip').text(prop.zip)
if(prop.pictures){
for (var i = 0; i < prop.pictures.length; i++) {
var myImg = prop.pictures[i]
$('.imgContainer').append($(`<div class="eachPicDiv"><img src="${myImg}" alt="0" class="detailPic">
<ion-icon class="rBtn" name="arrow-redo-outline"></ion-icon>
</div`))
}
} else {
$('.imgContainer').append($(`<h1>THERE WERE NO PICTURES</h1>`))
}
}

You are using jQuery to fetch your data from Firebase Database,
$.get is a jQuery method, and for that to succeed you need to have some sort of auth token.
Firebase already provides best in class access, read more about access here.
Learn by example here.

Related

Cant understand why im getting this error in .js webresource for MS Power Apps

As the title says, i cant seem to understand why im getting this error for an on change event on a model driven app form. i have to be honest, im using code snippits and chatGPT to try and formulate this because i haven't got a clue!! but i think im close 😁
for context, when i search for the client in a new enquiry for the code is to get the account manager from the clients record in another table and put it in the enquiry form.
var SDKEnquiry = window.Sdk || {}; (function(){ // This function is called when the customer lookup field on the form is changed this.function = onChangeCustomer(executionContext){ // Get the form context var formContext = executionContext.getFormContext();
// Get the value of the customer lookup field on the enquiry form
var customerLookup = formContext.getAttribute("customerlookup_on_enquiry_form").getValue();
// Check if a customer is selected
if(customerLookup){
// Retrieve the customer account record using the WebApi
Xrm.WebApi.retrieveRecord("account",
customerLookup[0].id, "?$select=accountmanagerid_on_customer_record").then(
function success(result) {
// Get the account manager id from the response
var accountManagerId = result.accountmanagerid_on_customer_record;
// Set the account manager id on the enquiry form
formContext.getAttribute("accountmanagerid_on_enquiry_form").setValue(accountManagerId);
},
function (error) {
// Show an error message
alert(error.message);
}
);
}
} }).call(SDKEnquiry);
This is the error im getting from Power Apps when i run the app and try and use the form. posted as image because im getting a spam warning
Error
Edit:
OKay so i think ive fixed the code, im not getting any errors anymore anyway but when i select the client the field does not pupulate?
var SDKEnquiry = {};
(function(){
this.onChangeCustomer = function(executionContext) {
var formContext = executionContext.getFormContext();
var customerLookup = formContext.getAttribute("w3c_clientcompany").getValue();
if (!customerLookup) {
alert("No customer selected.");
return;
}
Xrm.WebApi.retrieveRecord("account",
customerLookup[0].id, "?$select=w3c_AccountManager")
.then(function success(result) {
var accountManagerId = result.w3c_AccountManager;
formContext.getAttribute("w3c_cam").setValue(accountManagerId);
})
.catch(function (error) {
alert(error.message);
});
};
}).call(SDKEnquiry);

Meteor change database at run time

I have three database i.e, main_db it is default load database. I want load database after login.
Database are:-
main_db
->user_collection
psm_2017_db
->abc_collection
->xyz_collection
psm_2018_db
->abc_collection
->xyz_collection
Here is my project structure
here is my login script.
client
|->login
|->login.js
Template.login.rendered = function(){
SessionStore.set("login_user",false);
};
Template.login.events({
'submit #formLogin': function (event, target){
event.preventDefault();
var email = target.find('#loginEmail').value;
var password = target.find('#loginPassword').value;
// console.log(email +" "+password);
Meteor.loginWithPassword(email, password, function(err){
if(err){
console.log(err);
alert("Invalid Login!");
}
else {
SessionStore.set("login_user",true);
console.log('successfully')
Router.go("/dashboard")
}
});
}
});
Template.layout.helpers({
"isLoggedin": function () {
return SessionStore.get("login_user");
}
});
here is my load collection file
lib
|->collection.js
abcCollection=new Mongo.Collection("abc_collection");
xyzCollection=new Mongo.Collection("xyz_collection");
You can connect to multiple dbs using the below approach.
var database = new MongoInternals.RemoteCollectionDriver("<<mongo url>>");
MyCollection = new Mongo.Collection("collection_name", { _driver: database });
<<mongo_url>> is your standard mongodb url.
Eg. mongodb://127.0.0.1:27017/database_name
Now, in your specific scenario, main_db contains the user collection (I'm under the assumption that this is pertaining to meteor user collection). You need to have this loaded at all times. You can't have it load after login since user information - which is required for logging in resides in that db!
Once you take care of the above, connecting to the remaining two dbs can be done on login as below:
/lib/dbconnection.js (this will be common to both server and clinet)
Meteor.methods({
loadDB: function(){
if(Meteor.userId()){ // if a user has logged in
var database = new MongoInternals.RemoteCollectionDriver("<<mongo url>>");
MyCollection = new Mongo.Collection("collection_name", { _driver: database });
}
}
})
Meteor.call("loadDB");
loadDB will get called each time a user logs in. But I fear that it will be run each time any user logs in. In order to avoid it being re-initialized for each user login, you might want to do a check on whether database or myCollection already exists.

Promise to execute a particular code first

I have the following scenario. Actual Page loading starts, user login is checked for authentication. If access granted, actual page loading completes and user can access the page. If access denied, actual page loading stops and user is redirected to 'access denied' page.
Infact the scenario should be like this. User authentication is checked. if access granted, actual page loading starts and user can access page. If access denied, user is directly directed to 'access denied' page.
can someone tell me how to include promise for this scenario. current code is as follows.
$q.when().then(function () {
return $rootScope.$emit('resetView', false, 'default');
}).then(function (result) {
loadNavBar(); //actual page loading starts here
}, function (error) {
$log.error("Caught an error:", error);
return $q.reject('New error');
});
the below function is loadNavBar() which gets executed. User authentication is done inside of this. Hence page loading starts and then user is checked. I want user to be checked first itself and then load page accordingly depending on his access rights.
var loadNavBar = function () {
//few functions here to display page.
//below code to check user authentication
var serviceURL_CheckUserExists = '/api/Pre/CheckUserExists';
//ajax to check if user exists in database. give/ deny access based on user present in DB and if user is set as blockuser in db.
$.ajax({
type: "GET",
url: serviceURL_CheckUserExists,
}).then(function (response) {
if (response.Results.length == 1 && response.Results[0].BlockUser == false) { //user has access if condition is satisfied.
$rootScope.myLayout.eventHub.emit('getUserName', response.Results[0].User_ID.trim());
$scope.role = "";
var details = response.Results[0];
for (var parameters in details) {
if (details[parameters] == true) {
$scope.role += parameters + ',';
}
}
$scope.role = $scope.role.replace(/.$/, ".");
var firstname = response.Results[0].FirstName;
firstname = firstname.replace(/\s/g, '');
$scope.$apply(function () {
$scope.username = response.Results[0].FirstName + " " + response.Results[0].LastName;
});
}
else { $window.location.href = '../../../BlockUser.html'; } //block access to actual page and redirect to 'access denied' page.
}
}
});
};
i think that the right approach to your problem is to use resolve property in the route, so the user can't navigate to certain pages if he isn't logged in and once he logged in you can inject the user object to the controller
for example to navigate to home page you must be logged in
.when("/home", {
templateUrl: "homeView.html",
controller: "homeController",
resolve: {
user: function(AuthenticationService){
return AuthenticationService.getUser();
}
}
})
app.controller("homeController", function ($scope, user) {
$scope.user = user;
});
https://www.sitepoint.com/implementing-authentication-angular-applications/
Here's a quick example of hiding the content until the user is authenticated to see it. Click the 'authenticate' button to trigger the function that you would run if the user is authenticated by your ajax call. Showing the content can be done with a fuction like:
function userIsAuthenticated(){
document.getElementById('pageContent').style.display = 'block';
}
See JsFiddle for a simple implementation.

Add contacts Windows 10 Universal

Is it possible to programmatically add contacts to the adress book/ people app in Windows 10 like it is possible in Android?
I have a server on which contact information is stored, and I would like to make an app to synchronise my contacts with Windows 10.
I tried several things, but it didn't really work out. This is how far I've come:
Successfully download the contact data.
put the contact data in a Contact object.
This is what I've tried:
contacts.ContactManager.requestStoreAsync().done(function (contactStore) {
contactStore.createContactListAsync("name").done(function (contactList) {
for (i = 0; i < data.length; i++) {
var contact = new contacts.Contact;
//populate Contact item
contactList.saveContactAsync(contact);
}
contactList.saveAsync;
});
});
But I'm getting an acces denied error.
Any help would be appreciated. Thanks in advance!
Firstly, ensure you have added the contacts capability in app manifest.
<Capabilities>
<Capability Name="internetClient" />
<uap:Capability Name="contacts"/>
</Capabilities>
You will also get the access denied error if you had not request the read/write permission to the contact store.
ContactStoreAccessType enumeration
In this case, you can request the “appContactsReadWrite” permission.
But as I tested, there will be some API issues when calling the createContactListAsync method.
The current workaround is adding windows Runtime Component wrapper:
public sealed class ContactManagerWrapper
{
public IAsyncAction AddContactAsync(string userName, string email)
{
return AsyncInfo.Run(async (token) =>
{
var store = await ContactManager.RequestStoreAsync(ContactStoreAccessType.AppContactsReadWrite);
var contactLists = await store.FindContactListsAsync();
var contactList = contactLists.FirstOrDefault();
var contact = new Contact();
contact.Name = userName;
contact.Emails.Add(new ContactEmail() { Address = email, Kind = ContactEmailKind.Personal });
await contactList.SaveContactAsync(contact);
});
}
}
WinJS Project:
document.getElementById('click_me').addEventListener("click", function () {
var mgr = new UWPRuntimeComponent.ContactManagerWrapper();
mgr.addContactAsync('Jeffrey', 'jeffrey.chen#example.com').done(function () {
console.log("add contact successfully");
});
});
Try this
contacts.ContactManager.requestStoreAsync(ContactStoreAccessType.AppContactsReadWrite);
instead of this
contacts.ContactManager.requestStoreAsync()
you open the default store and I think its not accessible by developer.

Is there a very simple way to update a page in Perl Dancer using jQuery/AJAX?

I have the following code in my main Dancer app .pm:
package Deadlands;
use Dancer ':syntax';
use Dice;
our $VERSION = '0.1';
get '/' => sub {
my ($dieQty, $dieType, $bonus);
my $button = param('button');
$dieQty = param('dieQty');
$dieType = param('dieType');
$bonus = param('bonus');
if (defined $dieQty && defined $dieType) {
return Dice::Dice->new(dieType => $dieType, dieQty => $dieQty, bonus => $bonus)->getStandardResult();
}
template 'index';
};
true;
Here is my JavaScript:
$(document).ready(function() {
$('#standardRoll').click(function() {
$.get("/lib/Deadlands.pm", { button: '1', dieType: $("#dieType").val(), dieQty: $("#dieQty").val(), bonus: $("#bonus").val() }, processData);
function processData(data) {
$("#result").html(data);
}
});
});
I have a div in my web page called result that I want to be updated with the die roll result from Perl. Dancer keeps coming back with a 404 error in the command window when I push the submit button.
/lib/Deadlands.pm needs to be the URL of your route (probably / in this case), not the filesystem path of your Perl module.
Your AJAX request needs to point to a URL that actually exists, not a filename that has nothing to do with the web. Looks like $.get('/', ...) would do in this case.

Categories

Resources