GeoSaffer.com https://blog.geosaffer.com Apps, Electronics, 3D Printing & more Mon, 18 Nov 2024 23:36:42 +0000 en-US hourly 1 https://wordpress.org/?v=6.5.5 179389722 Implementing Authentication in a .NET 9 MAUI Blazor Hybrid App (SSR) https://blog.geosaffer.com/2024/11/20/187/?utm_source=rss&utm_medium=rss&utm_campaign=187 https://blog.geosaffer.com/2024/11/20/187/#respond Wed, 20 Nov 2024 08:00:12 +0000 https://blog.geosaffer.com/?p=187

Implementing Authentication in a .NET 9 MAUI Blazor Hybrid App (SSR)

This guide provides detailed steps to implement a basic username and password authentication system in a .NET 9 MAUI Blazor Hybrid app using the new Blazor Web App template with a .Shared project. The authentication system accounts for the limitations of server-side rendering (SSR) in Blazor Server applications and uses platform-specific authentication services.


Table of Contents

  1. Project Structure Overview
  2. Prerequisites
  3. Step-by-Step Implementation
  4. Additional Considerations
  5. Conclusion

Project Structure Overview

Your solution will consist of three projects:

  • YourApp.Web: The Blazor Server (Web) application.
  • YourApp.Mobile: The MAUI Blazor Hybrid (Mobile) application.
  • YourApp.Shared: Contains shared components, pages, and services.

Prerequisites

  • .NET 9 SDK: Ensure that you have the .NET 9 SDK installed.
  • Visual Studio 2022 (17.12 or later): For project creation and development.
  • MAUI Workload: Install the MAUI workload for cross-platform development.
  • Install the following Nuget Packages
      • In the .SharedProject
        • Microsoft.AspNetCore.Authorization (9.0.0)
        • Microsoft.AspNetCore.Components.Authorization (9.0.0)
        • Microsoft.AspNetCore.Components.Web (9.0.0)
        • Microsoft.Maui.Essentials (9.0.10)

Step-by-Step Implementation

Create a New Solution

  1. Open Visual Studio 2022.
  2. Create a New Project:
    • Template: Search for Blazor Web App.
    • Project Name: Enter YourApp.Web.
    • Solution Name: Enter YourApp.
  3. Add a MAUI Blazor App:
    • Right-click on the solution in Solution Explorer.
    • Select Add > New Project.
    • Choose .NET MAUI Blazor App.
    • Project Name: Enter YourApp.Mobile.
  4. Add a Class Library for Shared Code:
    • Right-click on the solution.
    • Select Add > New Project.
    • Choose Class Library.
    • Project Name: Enter YourApp.Shared.
  5. Add References:
    • In YourApp.Web and YourApp.Mobile, add a reference to YourApp.Shared.
  6. Set Up the Projects:
    • Ensure all projects target .NET 9.
    • Update the .csproj files if necessary.

Add some global usings for razor pages

In YourApp.Shared, open and edit _Imports.razor and add the following usings:

@using System.Net.Http
@using System.Net.Http.Json
@using Microsoft.AspNetCore.Components.Forms
@using Microsoft.AspNetCore.Components.Routing
@using Microsoft.AspNetCore.Components.Web
@using static Microsoft.AspNetCore.Components.Web.RenderMode
@using Microsoft.AspNetCore.Components.Web.Virtualization
@using Microsoft.JSInterop

@using Microsoft.AspNetCore.Authorization
@using Microsoft.AspNetCore.Components.Authorization;

@using YourApp.Shared.Layout
@using YourApp.Shared.Pages
@using YourApp.Shared.Services

Implement Platform-Specific Authentication Services

Due to the limitations of server-side rendering (SSR) in Blazor Server applications, we’ll implement platform-specific authentication services to handle authentication differently in the web and mobile applications.

Create an Interface for Authentication

In YourApp.Shared/Services, create ICustomAuthenticationService.cs:


// YourApp.Shared/Services/ICustomAuthenticationService.cs
using System.Security.Claims;
using System.Threading.Tasks;

namespace YourApp.Shared.Services
{
    public interface ICustomAuthenticationService
    {
        Task SignInAsync(string username);
        Task SignOutAsync();
        Task<ClaimsPrincipal> GetCurrentUserAsync();
    }
}

Implement the Authentication Service for Blazor Server

In YourApp.Web/Services, create ServerAuthenticationService.cs:


// YourApp.Web/Services/ServerAuthenticationService.cs
using System.Security.Claims;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Http;
using YourApp.Shared.Services;

namespace YourApp.Web.Services
{
    public class ServerAuthenticationService : ICustomAuthenticationService
    {
        private readonly IHttpContextAccessor _httpContextAccessor;

        public ServerAuthenticationService(IHttpContextAccessor httpContextAccessor)
        {
            _httpContextAccessor = httpContextAccessor;
        }

        public async Task SignInAsync(string username)
        {
            var claims = new[] { new Claim(ClaimTypes.Name, username) };
            var identity = new ClaimsIdentity(claims, "Cookies");
            var principal = new ClaimsPrincipal(identity);

            await _httpContextAccessor.HttpContext.SignInAsync("Cookies", principal);
        }

        public async Task SignOutAsync()
        {
            await _httpContextAccessor.HttpContext.SignOutAsync("Cookies");
        }

        public Task<ClaimsPrincipal> GetCurrentUserAsync()
        {
            var user = _httpContextAccessor.HttpContext.User;
            return Task.FromResult(user);
        }
    }
}

Update Program.cs in the Web Project

Configure authentication services in YourApp.Web/Program.cs:


// YourApp.Web/Program.cs
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Components.Authorization;
using YourApp.Shared.Services;
using YourApp.Web.Services;

var builder = WebApplication.CreateBuilder(args);

// Add services to the container.
builder.Services.AddRazorPages();
builder.Services.AddServerSideBlazor();

// Configure cookie authentication
builder.Services.AddAuthentication("Cookies")
    .AddCookie("Cookies", options =>
    {
        options.LoginPath = "/login";
    });

builder.Services.AddAuthorizationCore();

// Register IHttpContextAccessor
builder.Services.AddHttpContextAccessor();

// Register the server-specific authentication service
builder.Services.AddScoped<ICustomAuthenticationService, ServerAuthenticationService>();

// Register the custom AuthenticationStateProvider
builder.Services.AddScoped<AuthenticationStateProvider, ServerAuthenticationStateProvider>();

// Register UserService
builder.Services.AddScoped<UserService>();

var app = builder.Build();

// Configure the HTTP request pipeline.
app.UseStaticFiles();
app.UseRouting();

app.UseAuthentication();
app.UseAuthorization();

app.MapBlazorHub();
app.MapFallbackToPage("/_Host");

app.Run();

Create ServerAuthenticationStateProvider

In YourApp.Web/Services, create ServerAuthenticationStateProvider.cs:


// YourApp.Web/Services/ServerAuthenticationStateProvider.cs
using Microsoft.AspNetCore.Components.Authorization;
using System.Security.Claims;
using System.Threading.Tasks;
using YourApp.Shared.Services;

namespace YourApp.Web.Services
{
    public class ServerAuthenticationStateProvider : AuthenticationStateProvider
    {
        private readonly ICustomAuthenticationService _authenticationService;

        public ServerAuthenticationStateProvider(ICustomAuthenticationService authenticationService)
        {
            _authenticationService = authenticationService;
        }

        public override async Task<AuthenticationState> GetAuthenticationStateAsync()
        {
            var user = await _authenticationService.GetCurrentUserAsync();
            return new AuthenticationState(user);
        }
    }
}

Implement the Authentication Service for MAUI

In YourApp.Shared/Services, create CustomAuthenticationService.cs:


// YourApp.Shared/Services/CustomAuthenticationService.cs
using System.Security.Claims;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Components.Authorization;

namespace YourApp.Shared.Services
{
    public class CustomAuthenticationService : ICustomAuthenticationService
    {
        private readonly CustomAuthenticationStateProvider _authStateProvider;

        public CustomAuthenticationService(CustomAuthenticationStateProvider authStateProvider)
        {
            _authStateProvider = authStateProvider;
        }

        public async Task SignInAsync(string username)
        {
            await _authStateProvider.SignInAsync(username);
        }

        public async Task SignOutAsync()
        {
            await _authStateProvider.SignOutAsync();
        }

        public async Task<ClaimsPrincipal> GetCurrentUserAsync()
        {
            var authState = await _authStateProvider.GetAuthenticationStateAsync();
            return authState.User;
        }
    }
}

Adjust CustomAuthenticationStateProvider for MAUI

In YourApp.Shared/Services, update CustomAuthenticationStateProvider.cs:


// YourApp.Shared/Services/CustomAuthenticationStateProvider.cs
using System.Security.Claims;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Components.Authorization;
using Microsoft.Maui.Storage;

namespace YourApp.Shared.Services
{
    public class CustomAuthenticationStateProvider : AuthenticationStateProvider
    {
        private const string AuthDataKey = "authData";
        private ClaimsPrincipal _currentUser;

        public override async Task<AuthenticationState> GetAuthenticationStateAsync()
        {
            if (_currentUser != null)
            {
                return new AuthenticationState(_currentUser);
            }

            string username = await SecureStorage.Default.GetAsync(AuthDataKey);

            if (!string.IsNullOrWhiteSpace(username))
            {
                var identity = new ClaimsIdentity(new[]
                {
                    new Claim(ClaimTypes.Name, username)
                }, "apiauth_type");

                _currentUser = new ClaimsPrincipal(identity);
            }
            else
            {
                _currentUser = new ClaimsPrincipal(new ClaimsIdentity());
            }

            return new AuthenticationState(_currentUser);
        }

        public async Task SignInAsync(string username)
        {
            await SecureStorage.Default.SetAsync(AuthDataKey, username);

            var identity = new ClaimsIdentity(new[]
            {
                new Claim(ClaimTypes.Name, username)
            }, "apiauth_type");

            _currentUser = new ClaimsPrincipal(identity);

            NotifyAuthenticationStateChanged(GetAuthenticationStateAsync());
        }

        public async Task SignOutAsync()
        {
            SecureStorage.Default.Remove(AuthDataKey);

            _currentUser = new ClaimsPrincipal(new ClaimsIdentity());

            NotifyAuthenticationStateChanged(GetAuthenticationStateAsync());
        }
    }
}

Register Services in the MAUI Project

In YourApp.Mobile/MauiProgram.cs, register the authentication services:


// YourApp.Mobile/MauiProgram.cs
using Microsoft.AspNetCore.Components.Authorization;
using Microsoft.Extensions.DependencyInjection;
using YourApp.Shared.Services;

namespace YourApp.Mobile
{
    public static class MauiProgram
    {
        public static MauiApp CreateMauiApp()
        {
            var builder = MauiApp.CreateBuilder();

            builder
                .UseMauiApp<App>()
                .ConfigureFonts(fonts =>
                {
                    fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
                });

            builder.Services.AddMauiBlazorWebView();

    #if DEBUG
            builder.Services.AddBlazorWebViewDeveloperTools();
    #endif

            builder.Services.AddAuthorizationCore();

            // Register the custom authentication services
            builder.Services.AddScoped<CustomAuthenticationStateProvider>();
            builder.Services.AddScoped<AuthenticationStateProvider>(provider =>
                provider.GetRequiredService<CustomAuthenticationStateProvider>());

            builder.Services.AddScoped<ICustomAuthenticationService, CustomAuthenticationService>();

            // Register UserService
            builder.Services.AddScoped<UserService>();

            return builder.Build();
        }
    }
}

Implement a Simple User Store

Create UserService.cs in YourApp.Shared/Services:


// YourApp.Shared/Services/UserService.cs
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace YourApp.Shared.Services
{
    public class UserService
    {
        private List<UserCredential> _users = new List<UserCredential>
        {
            new UserCredential { Username = "user1", Password = "password1", Role = "User" },
            new UserCredential { Username = "admin", Password = "admin123", Role = "Admin" }
        };

        public Task<UserCredential> AuthenticateUserAsync(string username, string password)
        {
            var user = _users.FirstOrDefault(u => u.Username == username && u.Password == password);
            return Task.FromResult(user);
        }
    }

    public class UserCredential
    {
        public string Username { get; set; }
        public string Password { get; set; }
        public string Role { get; set; }
    }
}

Build Login and Logout Components

Create Login.razor

In YourApp.Shared/Pages, create Login.razor:


@page "/login"
@using YourApp.Shared.Services
@inject ICustomAuthenticationService AuthService
@inject UserService UserService
@inject NavigationManager NavigationManager

<h3>Login</h3>

@if (!string.IsNullOrEmpty(ErrorMessage))
{
    <div class="alert alert-danger">@ErrorMessage</div>
}

<EditForm Model="loginModel" OnValidSubmit="HandleLogin">
    <DataAnnotationsValidator />
    <ValidationSummary />

    <div>
        <label>Username:</label>
        <InputText @bind-Value="loginModel.Username" />
    </div>
    <div>
        <label>Password:</label>
        <InputText type="password" @bind-Value="loginModel.Password" />
    </div>
    <button type="submit">Login</button>
</EditForm>

@code {
    private LoginModel loginModel = new LoginModel();
    private string ErrorMessage;

    private async Task HandleLogin()
    {
        var user = await UserService.AuthenticateUserAsync(loginModel.Username, loginModel.Password);
        if (user != null)
        {
            await AuthService.SignInAsync(user.Username);
            NavigationManager.NavigateTo("/");
        }
        else
        {
            ErrorMessage = "Invalid username or password.";
        }
    }

    public class LoginModel
    {
        public string Username { get; set; }
        public string Password { get; set; }
    }
}

Create Logout.razor

In YourApp.Shared/Pages, create Logout.razor:


@page "/logout"
@using YourApp.Shared.Services
@inject ICustomAuthenticationService AuthService
@inject NavigationManager NavigationManager

<h3>Logging out...</h3>

@code {
    protected override async Task OnInitializedAsync()
    {
        await AuthService.SignOutAsync();
        NavigationManager.NavigateTo("/");
    }
}

Protect Pages with Authorization

Create a Protected Page

Create ProtectedPage.razor in YourApp.Shared/Pages:


@page "/protected"
@using Microsoft.AspNetCore.Authorization
@attribute [Authorize]
@inject ICustomAuthenticationService AuthService

<h3>Protected Page</h3>

<p>Welcome, @userName!</p>

@code {
    private string userName;

    protected override async Task OnInitializedAsync()
    {
        var user = await AuthService.GetCurrentUserAsync();
        userName = user.Identity?.Name;
    }
}

Update the Navigation Menu

In YourApp.Shared/Shared, update NavMenu.razor:


@inject AuthenticationStateProvider AuthenticationStateProvider
@implements IDisposable

<nav>
    <ul>
        <li><NavLink href="/">Home</NavLink></li>
        @if (isAuthenticated)
        {
            <li><NavLink href="protected">Protected Page</NavLink></li>
            <li><NavLink href="logout">Logout (@userName)</NavLink></li>
        }
        else
        {
            <li><NavLink href="login">Login</NavLink></li>
        }
    </ul>
</nav>

@code {
    private bool isAuthenticated;
    private string userName;
    private AuthenticationState authenticationState;

    protected override async Task OnInitializedAsync()
    {
        authenticationState = await AuthenticationStateProvider.GetAuthenticationStateAsync();
        UpdateAuthenticationState(authenticationState);

        AuthenticationStateProvider.AuthenticationStateChanged += OnAuthenticationStateChanged;
    }

    private void UpdateAuthenticationState(AuthenticationState authState)
    {
        var user = authState.User;
        isAuthenticated = user.Identity?.IsAuthenticated ?? false;
        userName = user.Identity?.Name;
        StateHasChanged();
    }

    private void OnAuthenticationStateChanged(Task<AuthenticationState> task)
    {
        InvokeAsync(async () =>
        {
            var authState = await task;
            UpdateAuthenticationState(authState);
        });
    }

    public void Dispose()
    {
        AuthenticationStateProvider.AuthenticationStateChanged -= OnAuthenticationStateChanged;
    }
}

Adjust Routing in Routes.razor

In YourApp.Shared, update Routes.razor:


@using Microsoft.AspNetCore.Components.Authorization
@using Microsoft.AspNetCore.Components.Routing

<CascadingAuthenticationState>
    <Router AppAssembly="@typeof(Routes).Assembly">
        <Found Context="routeData">
            <AuthorizeRouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)">
                <NotAuthorized>
                    @if (context.User.Identity.IsAuthenticated)
                    {
                        <p>You are not authorized to access this resource.</p>
                    }
                    else
                    {
                        <p>You are not authenticated. Please <a href="/login">log in</a>.</p>
                    }
                </NotAuthorized>
                <Authorizing>
                    <p>Authorizing...</p>
                </Authorizing>
            </AuthorizeRouteView>
        </Found>
        <NotFound>
            <LayoutView Layout="@typeof(MainLayout)">
                <p>Sorry, there's nothing at this address.</p>
            </LayoutView>
        </NotFound>
    </Router>
</CascadingAuthenticationState>

@code {
    [CascadingParameter]
    private Task<AuthenticationState> authenticationStateTask { get; set; }

    private AuthenticationState context => authenticationStateTask.Result;
}

Test the Application

Run the Web App

  1. Start the Web Project (YourApp.Web).
  2. Navigate to a Protected Page: Visit /protected.
  3. Verify Redirection: You should see a message indicating you are not authenticated.
  4. Log In: Navigate to /login and use user1 / password1.
  5. Access Protected Content: You should now see the protected page.

Run the Mobile App

  1. Start the Mobile Project (YourApp.Mobile).
  2. Repeat the Steps: Perform the same steps as above to verify authentication on mobile.

Additional Considerations

Persisting Authentication State

In the MAUI app, authentication state is persisted using SecureStorage. In the Blazor Server app, authentication state is managed via cookies using ASP.NET Core’s authentication mechanisms.

Enhancing Security

  • Password Hashing: Implement hashing for passwords instead of storing them in plain text.
  • Use HTTPS: Ensure your web application uses HTTPS to encrypt data in transit.
  • Input Validation: Validate all user inputs to prevent injection attacks.
  • External Authentication Providers: Consider integrating with OAuth or OpenID Connect for robust authentication.

Conclusion

By following these steps, you’ve successfully implemented a basic authentication system in your .NET 9 MAUI Blazor Hybrid app that accounts for the limitations of server-side rendering in Blazor Server applications. This setup allows you to:

  • Understand Platform-Specific Authentication: Manage authentication appropriately in both web and mobile environments.
  • Share Code Effectively: Use the .Shared project to share components and services between web and mobile apps.
  • Prepare for Future Enhancements: Lay the groundwork for integrating more secure and complex authentication mechanisms in the future.

Next Steps:

  • Implement Secure Authentication: Consider integrating OAuth or OpenID Connect for robust authentication.
  • Role-Based Authorization: Utilize roles to manage user access to different parts of the application.
  • UI/UX Improvements: Enhance the user interface for better usability and aesthetics.
]]>
https://blog.geosaffer.com/2024/11/20/187/feed/ 0 187
How to Implement and Use Google Translate API in C# https://blog.geosaffer.com/2024/11/19/how-to-implement-and-use-google-translate-api-in-c/?utm_source=rss&utm_medium=rss&utm_campaign=how-to-implement-and-use-google-translate-api-in-c https://blog.geosaffer.com/2024/11/19/how-to-implement-and-use-google-translate-api-in-c/#respond Tue, 19 Nov 2024 08:00:38 +0000 https://blog.geosaffer.com/?p=183 How to Implement and Use Google Translate API in C#

Welcome to this step-by-step tutorial on integrating the Google Translate API into your C# applications. Whether you’re building a multilingual application, need to translate user-generated content, or simply want to explore translation capabilities, this guide will help you get started.

Table of Contents

  1. Prerequisites
  2. Setting Up Google Cloud Translation API
  3. Creating a C# Project
  4. Writing the Code
  5. Running the Application
  6. Handling Common Issues
  7. Conclusion

1. Prerequisites

  • Google Cloud Account: You’ll need a Google Cloud account. If you don’t have one, you can create it here.
  • Basic Knowledge of C#: Familiarity with C# and .NET development.
  • Visual Studio: Install [Visual Studio](https://visualstudio.microsoft.com/) or any other C# IDE of your choice.

2. Setting Up Google Cloud Translation API

Before you can use the Google Translate API, you need to set it up in your Google Cloud account.

a. Create a New Project

  1. Go to the [Google Cloud Console](https://console.cloud.google.com/).
  2. Click on the project dropdown at the top and select New Project.
  3. Enter a project name and click Create.

b. Enable the Translation API

  1. Within your project in the Google Cloud Console, navigate to APIs & Services > Library.
  2. Search for “Cloud Translation API“.
  3. Select it and click Enable.

c. Create Service Account Credentials

  1. Go to APIs & Services > Credentials.
  2. Click on Create Credentials and select Service Account.
  3. Enter a service account name and description, then click Create.
  4. Assign the role Project > Editor (or a more restrictive role if preferred) and click Continue.
  5. Click Done.
  6. Find your newly created service account in the list, click the three dots on the right, and select Create key.
  7. Choose JSON as the key type and click Create. A JSON file will download to your computer. Keep this file secure!
Note: Do not expose your service account credentials publicly. Treat them like passwords.

3. Creating a C# Project

  1. Open Visual Studio.
  2. Click on Create a new project.
  3. Select Console App (.NET Core) or Console App (.NET Framework) based on your preference and click Next.
  4. Enter a project name (e.g., GoogleTranslateDemo) and click Create.

4. Writing the Code

Now, you’ll write the C# code to interact with the Google Translate API.

a. Install Required NuGet Packages

To use the Google Translate API, you need to install the Google.Cloud.Translation.V2 package.

  1. In Visual Studio, right-click on your project in the Solution Explorer and select Manage NuGet Packages….
  2. Go to the Browse tab, search for Google.Cloud.Translation.V2, select it, and click Install.

b. Add the Service Account Key

  1. Copy the downloaded JSON key file into your project directory.
  2. In Visual Studio, right-click on the JSON file in the Solution Explorer, select Properties, and set Copy to Output Directory to Copy if newer.

c. Implement the Translation Logic

Replace the content of Program.cs with the following code:

using System;
using Google.Cloud.Translation.V2;

namespace GoogleTranslateDemo
{
    class Program
    {
        static void Main(string[] args)
        {
            // Set the environment variable for authentication
            // Replace 'path-to-your-json-key-file.json' with the actual path
            Environment.SetEnvironmentVariable("GOOGLE_APPLICATION_CREDENTIALS", "path-to-your-json-key-file.json");

            // Create a client
            TranslationClient client = TranslationClient.Create();

            // Example text
            string text = "Hello, how are you today?";

            // Detect language
            var detection = client.DetectLanguage(text);
            Console.WriteLine($"Detected Language: {detection.Language} (Confidence: {detection.Confidence:P})");

            // Translate text to Spanish
            var translation = client.TranslateText(text, "es");
            Console.WriteLine($"\nTranslated Text to Spanish: {translation.TranslatedText}");

            // Translate text from Spanish back to English
            string spanishText = translation.TranslatedText;
            var translatedBack = client.TranslateText(spanishText, "en", "es");
            Console.WriteLine($"\nTranslated Back to English: {translatedBack.TranslatedText}");
        }
    }
}

d. Understanding the Code

  • Authentication: The environment variable GOOGLE_APPLICATION_CREDENTIALS is set to the path of your JSON key file. This allows the application to authenticate with Google Cloud.
  • TranslationClient: This client is used to interact with the Translation API.
  • DetectLanguage: Detects the language of the provided text.
  • TranslateText: Translates the provided text to the specified target language.
Note: Ensure that the path to your JSON key file is correct. You can use an absolute path or a relative path based on your project structure.

5. Running the Application

  1. Save all your changes in Visual Studio.
  2. Press F5 or click on Start to run the application.

Expected Output:


Detected Language: en (Confidence: 99.00%)

Translated Text to Spanish: Hola, ¿cómo estás hoy?

Translated Back to English: Hello, how are you today?

6. Handling Common Issues

a. Authentication Errors

If you encounter authentication errors, ensure that:

  • The GOOGLE_APPLICATION_CREDENTIALS environment variable points to the correct JSON key file.
  • The service account has the necessary permissions to use the Translation API.

b. Quota Exceeded

Google Cloud Translation API has usage quotas. If you exceed these quotas:

  • Check your [Google Cloud Quotas](https://console.cloud.google.com/iam-admin/quotas).
  • Consider requesting a quota increase if necessary.

c. Encoding Issues

If translations appear as question marks (????), ensure that:

  • Your console supports UTF-8 encoding.
  • Use fonts that support the characters of the target language.
Tip: For better security, avoid hardcoding the path to your JSON key file. Instead, set the environment variable outside the application or use secure secret management.

7. Conclusion

Congratulations! You’ve successfully integrated the Google Translate API into your C# application. This setup allows you to detect languages and translate text between multiple languages seamlessly.

Feel free to explore more features of the Google Cloud Translation API, such as batch translations, glossary support, and more to enhance your application’s multilingual capabilities.

If you encounter any issues or have questions, refer to the official [Google Cloud Translation API Documentation](https://cloud.google.com/translate/docs) or seek help from the community.

 

]]>
https://blog.geosaffer.com/2024/11/19/how-to-implement-and-use-google-translate-api-in-c/feed/ 0 183
Implementing Authentication in a .NET 9 MAUI Blazor Hybrid App https://blog.geosaffer.com/2024/11/18/180/?utm_source=rss&utm_medium=rss&utm_campaign=180 https://blog.geosaffer.com/2024/11/18/180/#respond Mon, 18 Nov 2024 03:24:04 +0000 https://blog.geosaffer.com/?p=180

Implementing Authentication in a .NET 9 MAUI Blazor Hybrid App

This guide provides detailed steps to implement a basic username and password authentication system in a .NET 9 MAUI Blazor Hybrid app using the new Blazor Web App template with a .Shared project. The authentication system uses a simple in-memory user store for demonstration purposes.


Table of Contents

  1. Project Structure Overview
  2. Prerequisites
  3. Step-by-Step Implementation
  4. Additional Considerations
  5. Conclusion

Project Structure Overview

Your solution will consist of three projects:

  • YourApp.Web: The Blazor Web App project.
  • YourApp.Mobile: The MAUI Blazor Hybrid project.
  • YourApp.Shared: Contains shared components, pages, and services.

Prerequisites

  • .NET 9 SDK: Ensure that you have the .NET 9 SDK installed.
  • Visual Studio 2022 (17.7 or later): For project creation and development.
  • MAUI Workload: Install the MAUI workload for cross-platform development.
  • Install the following Nuget Packages
      • In the .SharedProject
        • Microsoft.AspNetCore.Authorization (9.0.0)
        • Microsoft.AspNetCore.Components.Authorization (9.0.0)
        • Microsoft.AspNetCore.Components.Web (9.0.0)
        • Microsoft.Maui.Essentials (9.0.10)

Step-by-Step Implementation

Create a New Solution

  1. Open Visual Studio 2022.
  2. Create a New Project:
    • Template: Search for Blazor Web App.
    • Project Name: Enter YourApp.Web.
    • Solution Name: Enter YourApp.
  3. Add a MAUI Blazor App:
    • Right-click on the solution in Solution Explorer.
    • Select Add > New Project.
    • Choose .NET MAUI Blazor App.
    • Project Name: Enter YourApp.Mobile.
  4. Add a Class Library for Shared Code:
    • Right-click on the solution.
    • Select Add > New Project.
    • Choose Class Library.
    • Project Name: Enter YourApp.Shared.
  5. Add References:
    • In YourApp.Web and YourApp.Mobile, add a reference to YourApp.Shared.
  6. Set Up the Projects:
    • Ensure all projects target .NET 9.
    • Update the .csproj files if necessary.

Add some global usings for razor pages

In YourApp.Shared, open and edit _Imports.razor and add the following usings:


@using System.Net.Http
@using System.Net.Http.Json
@using Microsoft.AspNetCore.Components.Forms
@using Microsoft.AspNetCore.Components.Routing
@using Microsoft.AspNetCore.Components.Web
@using static Microsoft.AspNetCore.Components.Web.RenderMode
@using Microsoft.AspNetCore.Components.Web.Virtualization
@using Microsoft.JSInterop

@using Microsoft.AspNetCore.Authorization
@using Microsoft.AspNetCore.Components.Authorization;

@using YourApp.Shared.Layout
@using YourApp.Shared.Pages
@using YourApp.Shared.Services

Implement the Authentication State Provider

Create CustomAuthenticationStateProvider

In YourApp.Shared, create a new folder called Services and add the following class:


// YourApp.Shared/Services/CustomAuthenticationStateProvider.cs
using Microsoft.AspNetCore.Components.Authorization;
using System.Security.Claims;
using System.Threading.Tasks;

namespace YourApp.Shared.Services
{
    public class CustomAuthenticationStateProvider : AuthenticationStateProvider
    {
        private ClaimsPrincipal _anonymous = new ClaimsPrincipal(new ClaimsIdentity());
        private ClaimsPrincipal _currentUser;

        public override Task<AuthenticationState> GetAuthenticationStateAsync()
        {
            return Task.FromResult(new AuthenticationState(_currentUser ?? _anonymous));
        }

        public void SignIn(string username)
        {
            var identity = new ClaimsIdentity(new[]
            {
                new Claim(ClaimTypes.Name, username)
            }, "apiauth_type");

            _currentUser = new ClaimsPrincipal(identity);
            NotifyAuthenticationStateChanged(GetAuthenticationStateAsync());
        }

        public void SignOut()
        {
            _currentUser = _anonymous;
            NotifyAuthenticationStateChanged(GetAuthenticationStateAsync());
        }
    }
}

Register the Authentication State Provider

In YourApp.Web/Program.cs:


using YourApp.Shared.Services;
using Microsoft.AspNetCore.Components.Authorization;

var builder = WebApplication.CreateBuilder(args);

// Register services
builder.Services.AddRazorPages();
builder.Services.AddServerSideBlazor();

builder.Services.AddScoped<CustomAuthenticationStateProvider>();
builder.Services.AddScoped<AuthenticationStateProvider>(provider =>
    provider.GetRequiredService<CustomAuthenticationStateProvider>());
builder.Services.AddAuthorizationCore();

var app = builder.Build();

// Configure middleware
app.UseStaticFiles();
app.UseRouting();

app.MapBlazorHub();
app.MapFallbackToPage("/_Host");

app.Run();

In YourApp.Mobile/MauiProgram.cs:


using YourApp.Shared.Services;
using Microsoft.AspNetCore.Components.Authorization;

public static class MauiProgram
{
    public static MauiApp CreateMauiApp()
    {
        var builder = MauiApp.CreateBuilder();

        builder.UseMauiApp<App>();

        // Register services
        builder.Services.AddMauiBlazorWebView();
#if DEBUG
        builder.Services.AddBlazorWebViewDeveloperTools();
#endif

        builder.Services.AddScoped<CustomAuthenticationStateProvider>();
        builder.Services.AddScoped<AuthenticationStateProvider>(provider =>
            provider.GetRequiredService<CustomAuthenticationStateProvider>());
        builder.Services.AddAuthorizationCore();

        return builder.Build();
    }
}

Implement a Simple User Store

Create UserService.cs in YourApp.Shared/Services:


// YourApp.Shared/Services/UserService.cs
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace YourApp.Shared.Services
{
    public class UserService
    {
        private List<UserCredential> _users = new List<UserCredential>
        {
            new UserCredential { Username = "user1", Password = "password1", Role = "User" },
            new UserCredential { Username = "admin", Password = "admin123", Role = "Admin" }
        };

        public Task<UserCredential> AuthenticateUserAsync(string username, string password)
        {
            var user = _users.FirstOrDefault(u => u.Username == username && u.Password == password);
            return Task.FromResult(user);
        }
    }

    public class UserCredential
    {
        public string Username { get; set; }
        public string Password { get; set; }
        public string Role { get; set; }
    }
}

Register UserService in both Program.cs and MauiProgram.cs:


builder.Services.AddScoped<UserService>();

Build Login and Logout Components

Create Login.razor

In YourApp.Shared/Pages:


@page "/login"
@using YourApp.Shared.Services
@inject CustomAuthenticationStateProvider AuthStateProvider
@inject UserService UserService
@inject NavigationManager NavigationManager

<h3>Login</h3>

@if (!string.IsNullOrEmpty(ErrorMessage))
{
    <div class="alert alert-danger">@ErrorMessage</div>
}

<EditForm Model="loginModel" OnValidSubmit="HandleLogin">
    <DataAnnotationsValidator />
    <ValidationSummary />

    <div>
        <label>Username:</label>
        <InputText @bind-Value="loginModel.Username" />
    </div>
    <div>
        <label>Password:</label>
        <InputText type="password" @bind-Value="loginModel.Password" />
    </div>
    <button type="submit">Login</button>
</EditForm>

@code {
    private LoginModel loginModel = new LoginModel();
    private string ErrorMessage;

    private async Task HandleLogin()
    {
        var user = await UserService.AuthenticateUserAsync(loginModel.Username, loginModel.Password);
        if (user != null)
        {
            AuthStateProvider.SignIn(user.Username);
            NavigationManager.NavigateTo("/");
        }
        else
        {
            ErrorMessage = "Invalid username or password.";
        }
    }

    public class LoginModel
    {
        public string Username { get; set; }
        public string Password { get; set; }
    }
}

Create Logout.razor

In YourApp.Shared/Pages:


@page "/logout"
@inject CustomAuthenticationStateProvider AuthStateProvider
@inject NavigationManager NavigationManager

<h3>Logging out...</h3>

@code {
    protected override void OnInitialized()
    {
        AuthStateProvider.SignOut();
        NavigationManager.NavigateTo("/");
    }
}

Protect Pages with Authorization

Create a Protected Page

Create ProtectedPage.razor in YourApp.Shared/Pages:


@page "/protected"
@using Microsoft.AspNetCore.Authorization
@using Microsoft.AspNetCore.Components.Authorization
@attribute [Authorize]
@inject AuthenticationStateProvider AuthenticationStateProvider

<h3>Protected Page</h3>

<p>Welcome, @userName!</p>

@code {
    private string userName;

    protected override async Task OnInitializedAsync()
    {
        var authState = await AuthenticationStateProvider.GetAuthenticationStateAsync();
        var user = authState.User;
        userName = user.Identity?.Name;
    }
}

Ensure Required Packages Are Installed

Add the following NuGet packages to YourApp.Shared:

  • Microsoft.AspNetCore.Authorization
  • Microsoft.AspNetCore.Components.Authorization

Update the Navigation Menu

In YourApp.Shared/Shared, update NavMenu.razor:


@inject AuthenticationStateProvider AuthenticationStateProvider
@implements IDisposable

<nav>
    <ul>
        <li><NavLink href="/">Home</NavLink></li>
        @if (isAuthenticated)
        {
            <li><NavLink href="protected">Protected Page</NavLink></li>
            <li><NavLink href="logout">Logout (@userName)</NavLink></li>
        }
        else
        {
            <li><NavLink href="login">Login</NavLink></li>
        }
    </ul>
</nav>

@code {
    private bool isAuthenticated;
    private string userName;
    private AuthenticationState authenticationState;

    protected override async Task OnInitializedAsync()
    {
        authenticationState = await AuthenticationStateProvider.GetAuthenticationStateAsync();
        UpdateAuthenticationState(authenticationState);

        AuthenticationStateProvider.AuthenticationStateChanged += OnAuthenticationStateChanged;
    }

    private void UpdateAuthenticationState(AuthenticationState authState)
    {
        var user = authState.User;
        isAuthenticated = user.Identity?.IsAuthenticated ?? false;
        userName = user.Identity?.Name;
        StateHasChanged();
    }

    private void OnAuthenticationStateChanged(Task<AuthenticationState> task)
    {
        InvokeAsync(async () =>
        {
            var authState = await task;
            UpdateAuthenticationState(authState);
        });
    }

    public void Dispose()
    {
        AuthenticationStateProvider.AuthenticationStateChanged -= OnAuthenticationStateChanged;
    }
}

Adjust Routing in Routes.razor

In YourApp.Shared, update Routes.razor:


@using Microsoft.AspNetCore.Components.Authorization
@using Microsoft.AspNetCore.Components.Routing

<CascadingAuthenticationState>
    <Router AppAssembly="@typeof(Routes).Assembly">
        <Found Context="routeData">
            <AuthorizeRouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)">
                <NotAuthorized>
                    @if (context.User.Identity.IsAuthenticated)
                    {
                        <p>You are not authorized to access this resource.</p>
                    }
                    else
                    {
                        <RedirectToLogin />
                    }
                </NotAuthorized>
                <Authorizing>
                    <p>Authorizing...</p>
                </Authorizing>
            </AuthorizeRouteView>
        </Found>
        <NotFound>
            <LayoutView Layout="@typeof(MainLayout)">
                <p>Sorry, there's nothing at this address.</p>
            </LayoutView>
        </NotFound>
    </Router>
</CascadingAuthenticationState>

@code {
    [CascadingParameter]
    private Task<AuthenticationState> authenticationStateTask { get; set; }

    private AuthenticationState context => authenticationStateTask.Result;
}

Create RedirectToLogin.razor

In YourApp.Shared/Components:


@inject NavigationManager NavigationManager

@code {
    protected override void OnInitialized()
    {
        var returnUrl = Uri.EscapeDataString(NavigationManager.Uri);
        NavigationManager.NavigateTo($"/login?returnUrl={returnUrl}");
    }
}

Test the Application

Run the Web App

  1. Start the Web Project (YourApp.Web).
  2. Navigate to a Protected Page: Visit /protected.
  3. Verify Redirection: You should be redirected to the login page.
  4. Log In: Use user1 / password1.
  5. Access Protected Content: You should now see the protected page.

Run the Mobile App

  1. Start the Mobile Project (YourApp.Mobile).
  2. Repeat the Steps: Perform the same steps as above to verify authentication on mobile.

Additional Considerations

Persisting Authentication State

To persist authentication state across sessions, modify the CustomAuthenticationStateProvider to use secure storage.

Implementing Secure Storage

Update CustomAuthenticationStateProvider.cs:


using Microsoft.JSInterop;
using System.Text.Json;
using Microsoft.Maui.Storage;

public class CustomAuthenticationStateProvider : AuthenticationStateProvider
{
    private readonly IJSRuntime _jsRuntime;
    private const string _authDataKey = "authData";
    private ClaimsPrincipal _currentUser;

    public CustomAuthenticationStateProvider(IJSRuntime jsRuntime = null)
    {
        _jsRuntime = jsRuntime;
    }

    public override async Task<AuthenticationState> GetAuthenticationStateAsync()
    {
        if (_currentUser != null)
        {
            return new AuthenticationState(_currentUser);
        }

        string authDataJson = null;

#if ANDROID || IOS || WINDOWS
        authDataJson = await SecureStorage.Default.GetAsync(_authDataKey);
#else
        if (_jsRuntime != null)
        {
            authDataJson = await _jsRuntime.InvokeAsync<string>("localStorage.getItem", _authDataKey);
        }
#endif

        if (!string.IsNullOrWhiteSpace(authDataJson))
        {
            var authData = JsonSerializer.Deserialize<AuthData>(authDataJson);
            var identity = new ClaimsIdentity(new[]
            {
                new Claim(ClaimTypes.Name, authData.Username)
            }, "apiauth_type");

            _currentUser = new ClaimsPrincipal(identity);
        }
        else
        {
            _currentUser = new ClaimsPrincipal(new ClaimsIdentity());
        }

        return new AuthenticationState(_currentUser);
    }

    public async void SignIn(string username)
    {
        var identity = new ClaimsIdentity(new[]
        {
            new Claim(ClaimTypes.Name, username)
        }, "apiauth_type");

        _currentUser = new ClaimsPrincipal(identity);

        var authData = new AuthData { Username = username };
        var authDataJson = JsonSerializer.Serialize(authData);

#if ANDROID || IOS || WINDOWS
        await SecureStorage.Default.SetAsync(_authDataKey, authDataJson);
#else
        if (_jsRuntime != null)
        {
            await _jsRuntime.InvokeVoidAsync("localStorage.setItem", _authDataKey, authDataJson);
        }
#endif

        NotifyAuthenticationStateChanged(GetAuthenticationStateAsync());
    }

    public async void SignOut()
    {
        _currentUser = new ClaimsPrincipal(new ClaimsIdentity());

#if ANDROID || IOS || WINDOWS
        SecureStorage.Default.Remove(_authDataKey);
#else
        if (_jsRuntime != null)
        {
            await _jsRuntime.InvokeVoidAsync("localStorage.removeItem", _authDataKey);
        }
#endif

        NotifyAuthenticationStateChanged(GetAuthenticationStateAsync());
    }

    private class AuthData
    {
        public string Username { get; set; }
    }
}

Enhancing Security

  • Password Hashing: Implement hashing for passwords instead of storing them in plain text.
  • Use HTTPS: Ensure your web application uses HTTPS to encrypt data in transit.
  • Input Validation: Validate all user inputs to prevent injection attacks.

Conclusion

By following these steps, you’ve successfully implemented a basic authentication system in your .NET 9 MAUI Blazor Hybrid app using the new Blazor Web App template with a .Shared project. This setup allows you to:

  • Understand the Basics: Gain insights into how authentication works in Blazor and MAUI.
  • Share Code: Use the .Shared project to share components and services between web and mobile apps.
  • Prepare for Future Enhancements: Lay the groundwork for integrating more secure and complex authentication mechanisms in the future.

Next Steps:

  • Implement Secure Authentication: Consider integrating OAuth or OpenID Connect for robust authentication.
  • Role-Based Authorization: Utilize roles to manage user access to different parts of the application.
  • UI/UX Improvements: Enhance the user interface for better usability and aesthetics.

Feel free to customize this guide further or reach out if you have any questions or need additional assistance!

]]>
https://blog.geosaffer.com/2024/11/18/180/feed/ 0 180
Bluetooth Thermometer app – some new added features. https://blog.geosaffer.com/2021/01/04/add-some-new-features-to-the-bluetooth-thermometer-app/?utm_source=rss&utm_medium=rss&utm_campaign=add-some-new-features-to-the-bluetooth-thermometer-app Mon, 04 Jan 2021 22:07:02 +0000 https://blog.geosaffer.com/?p=174 Here is a video on the added features of the Bluetooth thermometer app

https://youtu.be/z5OnSWrEYCc

]]>
174
Drone Photos https://blog.geosaffer.com/2020/06/27/auto-draft/?utm_source=rss&utm_medium=rss&utm_campaign=auto-draft Sat, 27 Jun 2020 22:51:34 +0000 https://blog.geosaffer.com/?p=71 ]]> 71 Bluetooth Low Energy Thermometer https://blog.geosaffer.com/2019/12/26/bluetooth-low-energy-thermometer/?utm_source=rss&utm_medium=rss&utm_campaign=bluetooth-low-energy-thermometer Thu, 26 Dec 2019 08:56:50 +0000 http://blog.geosaffer.com/?p=67 You can create your own Bluetooth Low Energy Thermometer by just using a few components.

Some things you will need: 1. Arduino (Uno, Nano or Micro) We will be using the Uno for this demo.  

2. AT-09/HM-10 module  

3. DS18B20 thermal sensor

4. Some wires for connecting them (male to male, male to female and female to female)

5. a 4.7k resistor  6. an Android or iPhone

7. and finally the Arduino IDE  from Here  

Connecting all components

Connect everything up as shown in the diagram below, the connections are the same for HC-05 and AT-09

Required Libraries

Make sure to import the OneWire or 18b20 Library from Dallas Instruments

 

The Code to Run the project

Copy and paste the following code into your Arduino IDE or into the IDE of your choice  

// Include the libraries
#include <OneWire.h> 
#include <DallasTemperature.h>

// Data wire goes to pin 2 on the Arduino 
#define ONE_WIRE_BUS 2 

// Setup a oneWire instance
OneWire oneWire(ONE_WIRE_BUS); 

// Pass the oneWire reference to Dallas Temperature. 
DallasTemperature sensors(&oneWire);

void setup(void) 
{ 
 // start serial port with a baudrate of 9600 
 Serial.begin(9600); 
 Serial.println("Temperature Demo started"); 
 // Start up the sensor library 
 sensors.begin(); 
} 

void loop(void) 
{ 
  //request temprature
 sensors.requestTemperatures(); 
 // get the first sensors data 
 Serial.print(sensors.getTempCByIndex(0));  
 // finalize the string
 Serial.println("\r\n");
 //wait for 1 second before it reads again
 delay(1000); 
} 

Click the Verify button  to make sure there are no code errors and if it’s successful Click the Upload.

When the upload is successful, the program will start running on the Arduino.

 

Testing

When the upload is successful, open your serial monitor by pressing “Ctrl+Shft+M” If everything is working as expected you should see an output on the serial monitor every second.

 

Connecting to your Bluetooth Device

Once you have verified that the Arduino is getting data from your ds18b20, you are ready to connect your phone to your Bluetooth Module.

Download our app from the Google Play Store.   Once the app is installed, connect it to the (AT-09) with your app by selecting the device from the list.

Once you have selected the device tap the connect button top right and it will connect to it and you should shortly start seeing the data updating on the app.

]]>
67
Bluetooth Low Energy Thermometer App https://blog.geosaffer.com/2019/12/18/bluetooth-low-energy-thermometer-app/?utm_source=rss&utm_medium=rss&utm_campaign=bluetooth-low-energy-thermometer-app Wed, 18 Dec 2019 10:04:20 +0000 http://blog.geosaffer.com/?p=49
 

The Bluetooth LE thermometer app was created as a nice display of the data from my Bluetooth Low Energy Thermometer electronic project. The app uses Ble (Bluetooth Low Energy) to connect to an AT-09 or HM-10 low energy device or similar. Once the app is connected to the Bluetooth LE thermometer device, it will start listening for serial data.

The Bluetooth LE thermometer app has a text display with a Graphical Thermometer on the thermometer page. On the Graph page, it has a text display as well as a Graphical Graph showing the last 30 data points collected from the Bluetooth Thermometer.

You can make your own Bluetooth Thermometer using the AT-09 /HM-10 Bluetooth Low Energy module and connect it to an Arduino via the UART/Serial connections. Have a look at the Bluetooth Low Energy Thermometer electronics project to see how you can make your own BLE thermometer.

 

 

 

 

]]>
49
Bluetooth Thermometer App https://blog.geosaffer.com/2019/11/30/bluetooth-thermometer-app/?utm_source=rss&utm_medium=rss&utm_campaign=bluetooth-thermometer-app Sat, 30 Nov 2019 09:32:22 +0000 http://blog.geosaffer.com/?p=44

The Bluetooth thermometer app was created as a nice display of the data from my Bluetooth Thermometer electronic project.

The app uses legacy Bluetooth and therefore is only available on Android as iOS does not support it. This means that you can NOT connect to any Ble (Bluetooth Low Energy) device as it will not be picked up by the app. If you require an app for BLE please have a look at our Bluetooth LE Thermometer app.

Once the app is connected to the Bluetooth thermometer it will start listening for a decimal string ending with “\r\n” as the termination characters and will update the display as it receives data from the Bluetooth Thermometer.

At this point, the app only supports “\r\n” as termination characters, but we do have plans to add other termination strings if people request it.

The Bluetooth Thermometer App has a text display as well as a Graphical Thermometer on the thermometer page. On the Graph page, it has a text display as well as a Graphical Graph display showing the last 30 data points collected from the Bluetooth Thermometer.

You can make your own Bluetooth Thermometer using the HC-05 Bluetooth Module and connect it to an Arduino via the UART/Serial connections. Have a look at the Bluetooth Thermometer electronics project to see how you can make your own.

 

]]>
44
Bluetooth Thermometer https://blog.geosaffer.com/2019/10/30/bluetooth-thermometer/?utm_source=rss&utm_medium=rss&utm_campaign=bluetooth-thermometer Wed, 30 Oct 2019 08:13:37 +0000 http://blog.geosaffer.com/?p=18 You can create your own Bluetooth Thermometer by just using a few components.

Some things you will need:
1. Arduino (Uno, Nano or Micro)
We will be using the Uno for this demo.

 

2. HC-05 module

 

3. DS18B20 thermal sensor

4. Some wires for connecting them
(male to male, male to female and female to female)

5. a 4.7k resistor   

6. an Android phone

7. and finally the Arduino IDE  from Here

 

Connecting all components

Connect everything up as shown in the diagram below

Required Libraries

Make sure to import the OneWire or 18b20 Library from Dallas Instruments

 

The Code to Run the project

Copy and paste the following code into your Arduino IDE or into the IDE of your choice

 

// Include the libraries
#include <OneWire.h> 
#include <DallasTemperature.h>

// Data wire goes to pin 2 on the Arduino 
#define ONE_WIRE_BUS 2 

// Setup a oneWire instance
OneWire oneWire(ONE_WIRE_BUS); 

// Pass the oneWire reference to Dallas Temperature. 
DallasTemperature sensors(&oneWire);

void setup(void) 
{ 
 // start serial port with a baudrate of 9600 
 Serial.begin(9600); 
 Serial.println("Temperature Demo started"); 
 // Start up the sensor library 
 sensors.begin(); 
} 

void loop(void) 
{ 
  //request temprature
 sensors.requestTemperatures(); 
 // get the first sensors data 
 Serial.print(sensors.getTempCByIndex(0));  
 // finalize the string
 Serial.println("\r\n");
 //wait for 1 second before it reads again
 delay(1000); 
} 

Click the Verify button  to make sure there are no code errors
and if it’s successful Click the Upload.

When the upload is successful, the program will start running on the Arduino.

 

Testing

When the upload is successful, open your serial monitor by pressing “Ctrl+Shft+M”

If everything is working as expected you should see an output on the serial monitor every second.

 

Connecting to your Bluetooth Device

Once you have verified that the Arduino is getting data from your ds18b20, you are ready to connect your phone to your Bluetooth Module.

Download our app from the Google Play Store.

Once the app is installed, pair your Bluetooth Device(HC-05) with your phone.

Open the app on your phone and have a look for the paired device that you have just added to your phone and select it from the list.

Once you have selected the device it will connect to it and you should shortly start seeing the data updating on the app.

]]>
18
Summer is here! https://blog.geosaffer.com/2018/10/23/summer-is-here/?utm_source=rss&utm_medium=rss&utm_campaign=summer-is-here Tue, 23 Oct 2018 01:59:57 +0000 https://blog.geosaffer.com/?p=153 ]]> 153